From mboxrd@z Thu Jan 1 00:00:00 1970 From: zourongrong@huawei.com (Rongrong Zou) Date: Fri, 11 Nov 2016 19:16:51 +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> Message-ID: <5825A8A3.5070409@huawei.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org ? 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; ... }; ? > >> + >> + 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. > >> + >> + 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. > >> + 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; > >> + 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 ? > >> + 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()? > >> + >> +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. > > >> + 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 > > . > 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 19:16:51 +0800 Message-ID: <5825A8A3.5070409@huawei.com> References: <1477639682-22520-1-git-send-email-zourongrong@gmail.com> <1477639682-22520-3-git-send-email-zourongrong@gmail.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 , Rongrong Zou Cc: Mark Rutland , Archit , shenhui@huawei.com, Tomeu Vizoso , Jonathan Corbet , Dave Airlie , catalin.marinas@arm.com, Emil Velikov , linuxarm@huawei.com, dri-devel , xinliang.liu@linaro.org, james.xiong@huawei.com, daniel@fooishbar.org, Daniel Vetter , Will Deacon , lijianhua@huawei.com, Linux ARM Kernel , Benjamin Gaignard List-Id: dri-devel@lists.freedesktop.org 5ZyoIDIwMTYvMTEvMTEgMTozNSwgU2VhbiBQYXVsIOWGmemBkzoKPiBPbiBGcmksIE9jdCAyOCwg MjAxNiBhdCAzOjI3IEFNLCBSb25ncm9uZyBab3UgPHpvdXJvbmdyb25nQGdtYWlsLmNvbT4gd3Jv dGU6Cj4+IEhpYm1jIGhhdmUgMzJtIHZpZGVvIG1lbW9yeSB3aGljaCBjYW4gYmUgYWNjZXNzZWQg dGhyb3VnaCBQQ0llIGJ5IGhvc3QsCj4+IHdlIHVzZSB0dG0gdG8gbWFuYWdlIHRoZXNlIG1lbW9y eS4KPj4KPj4gU2lnbmVkLW9mZi1ieTogUm9uZ3JvbmcgWm91IDx6b3Vyb25ncm9uZ0BnbWFpbC5j b20+Cj4+IC0tLQo+PiAgIGRyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvS2NvbmZpZyAg ICAgICAgIHwgICAxICsKPj4gICBkcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL01ha2Vm aWxlICAgICAgICB8ICAgMiArLQo+PiAgIGRyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMv aGlibWNfZHJtX2Rydi5jIHwgIDEyICsKPj4gICBkcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hp Ym1jL2hpYm1jX2RybV9kcnYuaCB8ICA0NiArKysKPj4gICBkcml2ZXJzL2dwdS9kcm0vaGlzaWxp Y29uL2hpYm1jL2hpYm1jX3R0bS5jICAgICB8IDQ5MCArKysrKysrKysrKysrKysrKysrKysrKysK Pj4gICA1IGZpbGVzIGNoYW5nZWQsIDU1MCBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCj4+ ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvaGli bWNfdHRtLmMKPj4KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGli bWMvS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvS2NvbmZpZwo+PiBp bmRleCBhOWFmOTBkLi5iY2I4YzE4IDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vaGlz aWxpY29uL2hpYm1jL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9o aWJtYy9LY29uZmlnCj4+IEBAIC0xLDYgKzEsNyBAQAo+PiAgIGNvbmZpZyBEUk1fSElTSV9ISUJN Qwo+PiAgICAgICAgICB0cmlzdGF0ZSAiRFJNIFN1cHBvcnQgZm9yIEhpc2lsaWNvbiBIaWJtYyIK Pj4gICAgICAgICAgZGVwZW5kcyBvbiBEUk0gJiYgUENJCj4+ICsgICAgICAgc2VsZWN0IERSTV9U VE0KPj4KPj4gICAgICAgICAgaGVscAo+PiAgICAgICAgICAgIENob29zZSB0aGlzIG9wdGlvbiBp ZiB5b3UgaGF2ZSBhIEhpc2lsaWNvbiBIaWJtYyBzb2MgY2hpcHNldC4KPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9k cm0vaGlzaWxpY29uL2hpYm1jL01ha2VmaWxlCj4+IGluZGV4IDk3Y2Y0YTAuLmQ1YzQwYjggMTAw NjQ0Cj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvTWFrZWZpbGUKPj4g KysrIGIvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9NYWtlZmlsZQo+PiBAQCAtMSw1 ICsxLDUgQEAKPj4gICBjY2ZsYWdzLXkgOj0gLUlpbmNsdWRlL2RybQo+PiAtaGlibWMtZHJtLXkg Oj0gaGlibWNfZHJtX2Rydi5vIGhpYm1jX2RybV9wb3dlci5vCj4+ICtoaWJtYy1kcm0teSA6PSBo aWJtY19kcm1fZHJ2Lm8gaGlibWNfZHJtX3Bvd2VyLm8gaGlibWNfdHRtLm8KPj4KPj4gICBvYmot JChDT05GSUdfRFJNX0hJU0lfSElCTUMpICAgKz1oaWJtYy1kcm0ubwo+PiAgICNvYmoteSArPSBo aWJtYy1kcm0ubwo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJt Yy9oaWJtY19kcm1fZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1j X2RybV9kcnYuYwo+PiBpbmRleCA0NjY5ZDQyLi44MWY0MzAxIDEwMDY0NAo+PiAtLS0gYS9kcml2 ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYuYwo+PiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX2RybV9kcnYuYwo+PiBAQCAtMzEsNiAr MzEsNyBAQAo+PiAgICNpZmRlZiBDT05GSUdfQ09NUEFUCj4+ICAgICAgICAgIC5jb21wYXRfaW9j dGwgICA9IGRybV9jb21wYXRfaW9jdGwsCj4+ICAgI2VuZGlmCj4+ICsgICAgICAgLm1tYXAgICAg ICAgICAgID0gaGlibWNfbW1hcCwKPj4gICAgICAgICAgLnBvbGwgICAgICAgICAgID0gZHJtX3Bv bGwsCj4+ICAgICAgICAgIC5yZWFkICAgICAgICAgICA9IGRybV9yZWFkLAo+PiAgICAgICAgICAu bGxzZWVrICAgICAgICAgPSBub19sbHNlZWssCj4+IEBAIC00Niw2ICs0Nyw4IEBAIHN0YXRpYyB2 b2lkIGhpYm1jX2Rpc2FibGVfdmJsYW5rKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHVuc2lnbmVk IGludCBwaXBlKQo+PiAgIH0KPj4KPj4gICBzdGF0aWMgc3RydWN0IGRybV9kcml2ZXIgaGlibWNf ZHJpdmVyID0gewo+PiArICAgICAgIC5kcml2ZXJfZmVhdHVyZXMgICAgICAgID0gRFJJVkVSX0dF TSwKPj4gKwo+Cj4gbml0OiBleHRyYSBzcGFjZQo+Cj4+ICAgICAgICAgIC5mb3BzICAgICAgICAg ICAgICAgICAgID0gJmhpYm1jX2ZvcHMsCj4+ICAgICAgICAgIC5uYW1lICAgICAgICAgICAgICAg ICAgID0gImhpYm1jIiwKPj4gICAgICAgICAgLmRhdGUgICAgICAgICAgICAgICAgICAgPSAiMjAx NjA4MjgiLAo+PiBAQCAtNTUsNiArNTgsMTAgQEAgc3RhdGljIHZvaWQgaGlibWNfZGlzYWJsZV92 Ymxhbmsoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgdW5zaWduZWQgaW50IHBpcGUpCj4+ICAgICAg ICAgIC5nZXRfdmJsYW5rX2NvdW50ZXIgICAgID0gZHJtX3ZibGFua19ub19od19jb3VudGVyLAo+ PiAgICAgICAgICAuZW5hYmxlX3ZibGFuayAgICAgICAgICA9IGhpYm1jX2VuYWJsZV92Ymxhbmss Cj4+ICAgICAgICAgIC5kaXNhYmxlX3ZibGFuayAgICAgICAgID0gaGlibWNfZGlzYWJsZV92Ymxh bmssCj4+ICsgICAgICAgLmdlbV9mcmVlX29iamVjdF91bmxvY2tlZCA9IGhpYm1jX2dlbV9mcmVl X29iamVjdCwKPj4gKyAgICAgICAuZHVtYl9jcmVhdGUgICAgICAgICAgICA9IGhpYm1jX2R1bWJf Y3JlYXRlLAo+PiArICAgICAgIC5kdW1iX21hcF9vZmZzZXQgICAgICAgID0gaGlibWNfZHVtYl9t bWFwX29mZnNldCwKPj4gKyAgICAgICAuZHVtYl9kZXN0cm95ICAgICAgICAgICA9IGRybV9nZW1f ZHVtYl9kZXN0cm95LAo+PiAgIH07Cj4+Cj4+ICAgc3RhdGljIGludCBoaWJtY19wbV9zdXNwZW5k KHN0cnVjdCBkZXZpY2UgKmRldikKPj4gQEAgLTE2Myw2ICsxNzAsNyBAQCBzdGF0aWMgaW50IGhp Ym1jX3VubG9hZChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KQo+PiAgIHsKPj4gICAgICAgICAgc3Ry dWN0IGhpYm1jX2RybV9kZXZpY2UgKmhpZGV2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKPj4KPj4gKyAg ICAgICBoaWJtY19tbV9maW5pKGhpZGV2KTsKPj4gICAgICAgICAgaGlibWNfaHdfZmluaShoaWRl dik7Cj4+ICAgICAgICAgIGRldi0+ZGV2X3ByaXZhdGUgPSBOVUxMOwo+PiAgICAgICAgICByZXR1 cm4gMDsKPj4gQEAgLTE4Myw2ICsxOTEsMTAgQEAgc3RhdGljIGludCBoaWJtY19sb2FkKHN0cnVj dCBkcm1fZGV2aWNlICpkZXYsIHVuc2lnbmVkIGxvbmcgZmxhZ3MpCj4+ICAgICAgICAgIGlmIChy ZXQpCj4+ICAgICAgICAgICAgICAgICAgZ290byBlcnI7Cj4+Cj4+ICsgICAgICAgcmV0ID0gaGli bWNfbW1faW5pdChoaWRldik7Cj4+ICsgICAgICAgaWYgKHJldCkKPj4gKyAgICAgICAgICAgICAg IGdvdG8gZXJyOwo+PiArCj4+ICAgICAgICAgIHJldHVybiAwOwo+Pgo+PiAgIGVycjoKPj4gZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9oaXNpbGljb24vaGlibWMvaGlibWNfZHJtX2Rydi5o IGIvZHJpdmVycy9ncHUvZHJtL2hpc2lsaWNvbi9oaWJtYy9oaWJtY19kcm1fZHJ2LmgKPj4gaW5k ZXggMDAzNzM0MS4uZGI4ZDgwZSAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2hpc2ls aWNvbi9oaWJtYy9oaWJtY19kcm1fZHJ2LmgKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2hpc2ls aWNvbi9oaWJtYy9oaWJtY19kcm1fZHJ2LmgKPj4gQEAgLTIwLDYgKzIwLDggQEAKPj4gICAjZGVm aW5lIEhJQk1DX0RSTV9EUlZfSAo+Pgo+PiAgICNpbmNsdWRlIDxkcm0vZHJtUC5oPgo+PiArI2lu Y2x1ZGUgPGRybS90dG0vdHRtX2JvX2RyaXZlci5oPgo+PiArI2luY2x1ZGUgPGRybS9kcm1fZ2Vt Lmg+Cj4KPiBuaXQ6IGFscGhhYmV0aXplCgp3aWxsIGZpeCBpdCwgdGhhbmtzLgoKPgo+Pgo+PiAg IHN0cnVjdCBoaWJtY19kcm1fZGV2aWNlIHsKPj4gICAgICAgICAgLyogaHcgKi8KPj4gQEAgLTMw LDYgKzMyLDUwIEBAIHN0cnVjdCBoaWJtY19kcm1fZGV2aWNlIHsKPj4KPj4gICAgICAgICAgLyog ZHJtICovCj4+ICAgICAgICAgIHN0cnVjdCBkcm1fZGV2aWNlICAqZGV2Owo+PiArCj4+ICsgICAg ICAgLyogdHRtICovCj4+ICsgICAgICAgc3RydWN0IHsKPj4gKyAgICAgICAgICAgICAgIHN0cnVj dCBkcm1fZ2xvYmFsX3JlZmVyZW5jZSBtZW1fZ2xvYmFsX3JlZjsKPj4gKyAgICAgICAgICAgICAg IHN0cnVjdCB0dG1fYm9fZ2xvYmFsX3JlZiBib19nbG9iYWxfcmVmOwo+PiArICAgICAgICAgICAg ICAgc3RydWN0IHR0bV9ib19kZXZpY2UgYmRldjsKPj4gKyAgICAgICAgICAgICAgIGJvb2wgaW5p dGlhbGl6ZWQ7Cj4+ICsgICAgICAgfSB0dG07Cj4KPiBJIGRvbid0IHRoaW5rIHlvdSBnYWluIGFu eXRoaW5nIG90aGVyIHRoYW4ga2V5c3Ryb2tlcyBmcm9tIHRoZSBzdWJzdHJ1Y3QKCkknbSBzb3Jy eSBpIGRpZG4ndCBjYXRjaCB5b3UsIGkgbG9va2VkIGF0IHRoZSBhbGwgZHJpdmVycyB1c2VkIHR0 bSBzdWNoCmFzIGFzdC9ib2Nocy9jaXJydXMvbWdhZzIwMC9xeGwvdmlydGlvX2dwdSwgdGhleSBh bGwgZW1iZWRkZWQgdGhlIHR0bSBzdWJzdHJ1Y3QKaW50byB0aGUgZHJpdmVyLXByaXZhdGUgc3Ry dWN0LgoKc28gZG8geW91IG1lYW4Kc3RydWN0IGhpYm1jX2RybV9kZXZpY2UgewoJLyogaHcgKi8K CXZvaWQgX19pb21lbSAgICptbWlvOwoJdm9pZCBfX2lvbWVtICAgKmZiX21hcDsKCXVuc2lnbmVk IGxvbmcgIGZiX2Jhc2U7Cgl1bnNpZ25lZCBsb25nICBmYl9zaXplOwoKCS8qIGRybSAqLwoJc3Ry dWN0IGRybV9kZXZpY2UgICpkZXY7CglzdHJ1Y3QgZHJtX3BsYW5lIHBsYW5lOwoJc3RydWN0IGRy bV9jcnRjIGNydGM7CglzdHJ1Y3QgZHJtX2VuY29kZXIgZW5jb2RlcjsKCXN0cnVjdCBkcm1fY29u bmVjdG9yIGNvbm5lY3RvcjsKCWJvb2wgbW9kZV9jb25maWdfaW5pdGlhbGl6ZWQ7CgoJLyogdHRt ICovCglzdHJ1Y3QgZHJtX2dsb2JhbF9yZWZlcmVuY2UgbWVtX2dsb2JhbF9yZWY7CglzdHJ1Y3Qg dHRtX2JvX2dsb2JhbF9yZWYgYm9fZ2xvYmFsX3JlZjsKCXN0cnVjdCB0dG1fYm9fZGV2aWNlIGJk ZXY7Cglib29sIGluaXRpYWxpemVkOwoJLi4uCgl9Owo/Cgo+Cj4+ICsKPj4gKyAgICAgICBib29s IG1tX2luaXRlZDsKPj4gICB9Owo+Pgo+PiArc3RydWN0IGhpYm1jX2JvIHsKPj4gKyAgICAgICBz dHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QgYm87Cj4+ICsgICAgICAgc3RydWN0IHR0bV9wbGFjZW1l bnQgcGxhY2VtZW50Owo+PiArICAgICAgIHN0cnVjdCB0dG1fYm9fa21hcF9vYmoga21hcDsKPj4g KyAgICAgICBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgZ2VtOwo+PiArICAgICAgIHN0cnVjdCB0dG1f cGxhY2UgcGxhY2VtZW50c1szXTsKPj4gKyAgICAgICBpbnQgcGluX2NvdW50Owo+PiArfTsKPj4g Kwo+PiArc3RhdGljIGlubGluZSBzdHJ1Y3QgaGlibWNfYm8gKmhpYm1jX2JvKHN0cnVjdCB0dG1f YnVmZmVyX29iamVjdCAqYm8pCj4+ICt7Cj4+ICsgICAgICAgcmV0dXJuIGNvbnRhaW5lcl9vZihi bywgc3RydWN0IGhpYm1jX2JvLCBibyk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbmxpbmUgc3Ry dWN0IGhpYm1jX2JvICpnZW1fdG9faGlibWNfYm8oc3RydWN0IGRybV9nZW1fb2JqZWN0ICpnZW0p Cj4+ICt7Cj4+ICsgICAgICAgcmV0dXJuIGNvbnRhaW5lcl9vZihnZW0sIHN0cnVjdCBoaWJtY19i bywgZ2VtKTsKPj4gK30KPj4gKwo+PiArI2RlZmluZSBEUk1fRklMRV9QQUdFX09GRlNFVCAoMHgx MDAwMDAwMDBVTEwgPj4gUEFHRV9TSElGVCkKPgo+IEhpZGUgdGhpcyBpbiB0dG0uYwoKb2ssIHdp bGwgZG8gdGhhdC4KdGhhbmtzIGZvciBwb2ludGluZyBpdCBvdXQuCgo+Cj4+ICsKPj4gK2ludCBo aWJtY19nZW1fY3JlYXRlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHUzMiBzaXplLCBib29sIGlz a2VybmVsLAo+PiArICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKipv YmopOwo+PiArCj4+ICtpbnQgaGlibWNfbW1faW5pdChzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAq aGlibWMpOwo+PiArdm9pZCBoaWJtY19tbV9maW5pKHN0cnVjdCBoaWJtY19kcm1fZGV2aWNlICpo aWJtYyk7Cj4+ICtpbnQgaGlibWNfYm9fcGluKHN0cnVjdCBoaWJtY19ibyAqYm8sIHUzMiBwbF9m bGFnLCB1NjQgKmdwdV9hZGRyKTsKPj4gK3ZvaWQgaGlibWNfZ2VtX2ZyZWVfb2JqZWN0KHN0cnVj dCBkcm1fZ2VtX29iamVjdCAqb2JqKTsKPj4gK2ludCBoaWJtY19kdW1iX2NyZWF0ZShzdHJ1Y3Qg ZHJtX2ZpbGUgKmZpbGUsIHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4+ICsgICAgICAgICAgICAg ICAgICAgICBzdHJ1Y3QgZHJtX21vZGVfY3JlYXRlX2R1bWIgKmFyZ3MpOwo+PiAraW50IGhpYm1j X2R1bWJfbW1hcF9vZmZzZXQoc3RydWN0IGRybV9maWxlICpmaWxlLCBzdHJ1Y3QgZHJtX2Rldmlj ZSAqZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICB1MzIgaGFuZGxlLCB1NjQgKm9m ZnNldCk7Cj4+ICtpbnQgaGlibWNfbW1hcChzdHJ1Y3QgZmlsZSAqZmlscCwgc3RydWN0IHZtX2Fy ZWFfc3RydWN0ICp2bWEpOwo+PiArCj4+ICAgI2VuZGlmCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vaGlzaWxpY29uL2hpYm1jL2hpYm1jX3R0bS5jIGIvZHJpdmVycy9ncHUvZHJtL2hp c2lsaWNvbi9oaWJtYy9oaWJtY190dG0uYwo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRl eCAwMDAwMDAwLi4wODAyZWJkCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL2hpc2lsaWNvbi9oaWJtYy9oaWJtY190dG0uYwo+PiBAQCAtMCwwICsxLDQ5MCBAQAo+PiAr LyogSGlzaWxpY29uIEhpYm1jIFNvQyBkcm0gZHJpdmVyCj4+ICsgKgo+PiArICogQmFzZWQgb24g dGhlIGJvY2hzIGRybSBkcml2ZXIuCj4+ICsgKgo+PiArICogQ29weXJpZ2h0IChjKSAyMDE2IEh1 YXdlaSBMaW1pdGVkLgo+PiArICoKPj4gKyAqIEF1dGhvcjoKPj4gKyAqICAgICBSb25ncm9uZyBa b3UgPHpvdXJvbmdyb25nQGh1YXdlaS5jb20+Cj4+ICsgKiAgICAgUm9uZ3JvbmcgWm91IDx6b3Vy b25ncm9uZ0BnbWFpbC5jb20+Cj4+ICsgKiAgICAgSmlhbmh1YSBMaSA8bGlqaWFuaHVhQGh1YXdl aS5jb20+Cj4+ICsgKgo+PiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBj YW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKPj4gKyAqIGl0IHVuZGVyIHRoZSB0ZXJt cyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5Cj4+ICsg KiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBM aWNlbnNlLCBvcgo+PiArICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPj4g KyAqCj4+ICsgKi8KPj4gKwo+PiArI2luY2x1ZGUgImhpYm1jX2RybV9kcnYuaCIKPj4gKyNpbmNs dWRlIDx0dG0vdHRtX3BhZ2VfYWxsb2MuaD4KPj4gKyNpbmNsdWRlIDxkcm0vZHJtX2NydGNfaGVs cGVyLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9hdG9taWNfaGVscGVyLmg+Cj4+ICsKPj4gK3N0 YXRpYyBpbmxpbmUgc3RydWN0IGhpYm1jX2RybV9kZXZpY2UgKgo+PiAraGlibWNfYmRldihzdHJ1 Y3QgdHRtX2JvX2RldmljZSAqYmQpCj4+ICt7Cj4+ICsgICAgICAgcmV0dXJuIGNvbnRhaW5lcl9v ZihiZCwgc3RydWN0IGhpYm1jX2RybV9kZXZpY2UsIHR0bS5iZGV2KTsKPj4gK30KPj4gKwo+PiAr c3RhdGljIGludAo+PiAraGlibWNfdHRtX21lbV9nbG9iYWxfaW5pdChzdHJ1Y3QgZHJtX2dsb2Jh bF9yZWZlcmVuY2UgKnJlZikKPj4gK3sKPj4gKyAgICAgICByZXR1cm4gdHRtX21lbV9nbG9iYWxf aW5pdChyZWYtPm9iamVjdCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkCj4+ICtoaWJtY190 dG1fbWVtX2dsb2JhbF9yZWxlYXNlKHN0cnVjdCBkcm1fZ2xvYmFsX3JlZmVyZW5jZSAqcmVmKQo+ PiArewo+PiArICAgICAgIHR0bV9tZW1fZ2xvYmFsX3JlbGVhc2UocmVmLT5vYmplY3QpOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgaW50IGhpYm1jX3R0bV9nbG9iYWxfaW5pdChzdHJ1Y3QgaGlibWNf ZHJtX2RldmljZSAqaGlibWMpCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IGRybV9nbG9iYWxfcmVm ZXJlbmNlICpnbG9iYWxfcmVmOwo+PiArICAgICAgIGludCByOwo+Cj4gbml0OiB0cnkgbm90IHRv IHVzZSBvbmUgY2hhcmFjdGVyIHZhcmlhYmxlIG5hbWVzIHVubGVzcyBpdCdzIGZvciB0aGUKPiBw dXJwb3NlIG9mIGEgbG9vcCAoaWU6IGksaikuIFlvdSBhbHNvIHVzZSByZXQgZWxzZXdoZXJlIGlu IHRoZSBkcml2ZXIsCj4gc28gaXQnZCBiZSBuaWNlIHRvIHJlbWFpbiBjb25zaXN0ZW50Cgp0aGUg d2hvbGUgZmlsZSBpcyBkZWxpdmVyZWQgZnJvbSBib2NocyB0dG0sIGkgZGlkbid0IG1vZGlmeSBh bnl0aGluZyBleGNlcHQKc29tZSBjaGVja3BhdGNoIHdhcm5pbmdzIGFuZCB0aGUgJ2hpYm1jXycg cHJlZml4LiBVbmZvcnR1bmF0ZWx5LCBzb21lCnByb2JsZW1zIHdlcmUgZGVsaXZlcmVkIHRvby4K Cj4KPj4gKwo+PiArICAgICAgIGdsb2JhbF9yZWYgPSAmaGlibWMtPnR0bS5tZW1fZ2xvYmFsX3Jl ZjsKPgo+IEkgdGhpbmsgdXNpbmcgdGhlIGdsb2JhbF9yZWYgbG9jYWwgb2JmdXNjYXRlcyB3aGF0 IHlvdSdyZSBkb2luZyBoZXJlLgo+IEl0IHNhdmVzIHlvdSA2IGNoYXJhY3RlcnMgd2hpbGUgdHlw aW5nLCBidXQgYWRkcyBhIGxheWVyIG9mCj4gaW5kaXJlY3Rpb24gZm9yIGFsbCBmdXR1cmUgcmVh ZGVycy4KPgo+PiArICAgICAgIGdsb2JhbF9yZWYtPmdsb2JhbF90eXBlID0gRFJNX0dMT0JBTF9U VE1fTUVNOwo+PiArICAgICAgIGdsb2JhbF9yZWYtPnNpemUgPSBzaXplb2Yoc3RydWN0IHR0bV9t ZW1fZ2xvYmFsKTsKPj4gKyAgICAgICBnbG9iYWxfcmVmLT5pbml0ID0gJmhpYm1jX3R0bV9tZW1f Z2xvYmFsX2luaXQ7Cj4+ICsgICAgICAgZ2xvYmFsX3JlZi0+cmVsZWFzZSA9ICZoaWJtY190dG1f bWVtX2dsb2JhbF9yZWxlYXNlOwo+PiArICAgICAgIHIgPSBkcm1fZ2xvYmFsX2l0ZW1fcmVmKGds b2JhbF9yZWYpOwo+PiArICAgICAgIGlmIChyICE9IDApIHsKPgo+IG5pdDogaWYgKHIpCgp3aWxs IGZpeCBpdCwKdGhhbmtzLgpCVFcsIGkgd29uZGVyIHdoeSBjaGVja3BhdGNoLnBsIGRpZG4ndCBy ZXBvcnQgaXQuCgoKPgo+PiArICAgICAgICAgICAgICAgRFJNX0VSUk9SKCJGYWlsZWQgc2V0dGlu ZyB1cCBUVE0gbWVtb3J5IGFjY291bnRpbmcgc3Vic3lzdGVtLlxuIgo+PiArICAgICAgICAgICAg ICAgICAgICAgICAgKTsKPgo+IEJyZWFraW5nIHVwIHRoZSBsaW5lIGZvciBvbmUgY2hhcmFjdGVy IGlzIHByb2JhYmx5IG5vdCB3b3J0aHdoaWxlLCBhbmQKPiB5b3Ugc2hvdWxkIHJlYWxseSBwcmlu dCB0aGUgZXJyb3IuIEhvdyBhYm91dDoKPgo+IERSTV9FUlJPUigiQ291bGQgbm90IGdldCByZWYg b24gdHRtIGdsb2JhbCByZXQ9JWQuXG4iLCByZXQpOwoKaSBsaWtlIHlvdXIgc29sdXRpb24sIHRo YW5rcy4KCj4KPgo+PiArICAgICAgICAgICAgICAgcmV0dXJuIHI7Cj4+ICsgICAgICAgfQo+PiAr Cj4+ICsgICAgICAgaGlibWMtPnR0bS5ib19nbG9iYWxfcmVmLm1lbV9nbG9iID0KPj4gKyAgICAg ICAgICAgICAgIGhpYm1jLT50dG0ubWVtX2dsb2JhbF9yZWYub2JqZWN0Owo+PiArICAgICAgIGds b2JhbF9yZWYgPSAmaGlibWMtPnR0bS5ib19nbG9iYWxfcmVmLnJlZjsKPj4gKyAgICAgICBnbG9i YWxfcmVmLT5nbG9iYWxfdHlwZSA9IERSTV9HTE9CQUxfVFRNX0JPOwo+PiArICAgICAgIGdsb2Jh bF9yZWYtPnNpemUgPSBzaXplb2Yoc3RydWN0IHR0bV9ib19nbG9iYWwpOwo+PiArICAgICAgIGds b2JhbF9yZWYtPmluaXQgPSAmdHRtX2JvX2dsb2JhbF9pbml0Owo+PiArICAgICAgIGdsb2JhbF9y ZWYtPnJlbGVhc2UgPSAmdHRtX2JvX2dsb2JhbF9yZWxlYXNlOwo+PiArICAgICAgIHIgPSBkcm1f Z2xvYmFsX2l0ZW1fcmVmKGdsb2JhbF9yZWYpOwo+PiArICAgICAgIGlmIChyICE9IDApIHsKPj4g KyAgICAgICAgICAgICAgIERSTV9FUlJPUigiRmFpbGVkIHNldHRpbmcgdXAgVFRNIEJPIHN1YnN5 c3RlbS5cbiIpOwo+PiArICAgICAgICAgICAgICAgZHJtX2dsb2JhbF9pdGVtX3VucmVmKCZoaWJt Yy0+dHRtLm1lbV9nbG9iYWxfcmVmKTsKPj4gKyAgICAgICAgICAgICAgIHJldHVybiByOwo+PiAr ICAgICAgIH0KPj4gKyAgICAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQK Pj4gK2hpYm1jX3R0bV9nbG9iYWxfcmVsZWFzZShzdHJ1Y3QgaGlibWNfZHJtX2RldmljZSAqaGli bWMpCj4+ICt7Cj4+ICsgICAgICAgaWYgKCFoaWJtYy0+dHRtLm1lbV9nbG9iYWxfcmVmLnJlbGVh c2UpCj4KPiBBcmUgeW91IGFjdHVhbGx5IGhpdHRpbmcgdGhpcyBjb25kaXRpb24/IFRoaXMgc2Vl bXMgbGlrZSBpdCdzIHBhcGVyaW5nCj4gb3ZlciBzb21ldGhpbmcgZWxzZS4KCml0IHdhcyBhbHNv IGRlbGl2ZXJlZCBmcm9tIG90aGVycywgaSBsb29rZWQgYXQgdGhlIHh4eF90dG1fZ2xvYmFsX2lu aXQKZnVuY3Rpb24sICdtZW1fZ2xvYmFsX3JlZi5yZWxlYXNlJyBpcyBhc3NpZ25lZCB1bmNvbmRp dGlvbmFsbHksIHNvIGkKdGhpbmsgdGhpcyBjb25kaXRpb24gbmV2ZXIgYmUgaGl0LCBpdCBtYXkg YmUgaGl0IHdoZW4gcmVsZWFzZSB0d2ljZSwKYnV0IHRoaXMgd29uJ3QgdGFrZSBwbGFjZSBpbiBt eSBkcml2ZXIuCgo+Cj4+ICsgICAgICAgICAgICAgICByZXR1cm47Cj4+ICsKPj4gKyAgICAgICBk cm1fZ2xvYmFsX2l0ZW1fdW5yZWYoJmhpYm1jLT50dG0uYm9fZ2xvYmFsX3JlZi5yZWYpOwo+PiAr ICAgICAgIGRybV9nbG9iYWxfaXRlbV91bnJlZigmaGlibWMtPnR0bS5tZW1fZ2xvYmFsX3JlZik7 Cj4+ICsgICAgICAgaGlibWMtPnR0bS5tZW1fZ2xvYmFsX3JlZi5yZWxlYXNlID0gTlVMTDsKPj4g K30KPj4gKwo+PiArc3RhdGljIHZvaWQgaGlibWNfYm9fdHRtX2Rlc3Ryb3koc3RydWN0IHR0bV9i dWZmZXJfb2JqZWN0ICp0Ym8pCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2JvICpibzsK Pj4gKwo+PiArICAgICAgIGJvID0gY29udGFpbmVyX29mKHRibywgc3RydWN0IGhpYm1jX2JvLCBi byk7Cj4KPiBuaXQ6IE5vIG5lZWQgdG8gc3BsaXQgdGhpcyBpbnRvIGEgc2VwYXJhdGUgbGluZS4K CmFncmVlZCwgdGhhbmtzLgoKPgo+PiArCj4+ICsgICAgICAgZHJtX2dlbV9vYmplY3RfcmVsZWFz ZSgmYm8tPmdlbSk7Cj4+ICsgICAgICAga2ZyZWUoYm8pOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg Ym9vbCBoaWJtY190dG1fYm9faXNfaGlibWNfYm8oc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICpi bykKPj4gK3sKPj4gKyAgICAgICBpZiAoYm8tPmRlc3Ryb3kgPT0gJmhpYm1jX2JvX3R0bV9kZXN0 cm95KQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7Cj4+ICsgICAgICAgcmV0dXJuIGZh bHNlOwo+Cj4gcmV0dXJuIGJvLT5kZXN0cm95ID09ICZoaWJtY19ib190dG1fZGVzdHJveTsKCmxv b2tzIGJldHRlciB0byBtZS4KCj4KPj4gK30KPj4gKwo+PiArc3RhdGljIGludAo+PiAraGlibWNf Ym9faW5pdF9tZW1fdHlwZShzdHJ1Y3QgdHRtX2JvX2RldmljZSAqYmRldiwgdTMyIHR5cGUsCj4+ ICsgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHR0bV9tZW1fdHlwZV9tYW5hZ2VyICptYW4p Cj4+ICt7Cj4+ICsgICAgICAgc3dpdGNoICh0eXBlKSB7Cj4+ICsgICAgICAgY2FzZSBUVE1fUExf U1lTVEVNOgo+PiArICAgICAgICAgICAgICAgbWFuLT5mbGFncyA9IFRUTV9NRU1UWVBFX0ZMQUdf TUFQUEFCTEU7Cj4+ICsgICAgICAgICAgICAgICBtYW4tPmF2YWlsYWJsZV9jYWNoaW5nID0gVFRN X1BMX01BU0tfQ0FDSElORzsKPj4gKyAgICAgICAgICAgICAgIG1hbi0+ZGVmYXVsdF9jYWNoaW5n ID0gVFRNX1BMX0ZMQUdfQ0FDSEVEOwo+PiArICAgICAgICAgICAgICAgYnJlYWs7Cj4+ICsgICAg ICAgY2FzZSBUVE1fUExfVlJBTToKPj4gKyAgICAgICAgICAgICAgIG1hbi0+ZnVuYyA9ICZ0dG1f Ym9fbWFuYWdlcl9mdW5jOwo+PiArICAgICAgICAgICAgICAgbWFuLT5mbGFncyA9IFRUTV9NRU1U WVBFX0ZMQUdfRklYRUQgfAo+PiArICAgICAgICAgICAgICAgICAgICAgICBUVE1fTUVNVFlQRV9G TEFHX01BUFBBQkxFOwo+PiArICAgICAgICAgICAgICAgbWFuLT5hdmFpbGFibGVfY2FjaGluZyA9 IFRUTV9QTF9GTEFHX1VOQ0FDSEVEIHwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgVFRNX1BM X0ZMQUdfV0M7Cj4+ICsgICAgICAgICAgICAgICBtYW4tPmRlZmF1bHRfY2FjaGluZyA9IFRUTV9Q TF9GTEFHX1dDOwo+PiArICAgICAgICAgICAgICAgYnJlYWs7Cj4+ICsgICAgICAgZGVmYXVsdDoK Pj4gKyAgICAgICAgICAgICAgIERSTV9FUlJPUigiVW5zdXBwb3J0ZWQgbWVtb3J5IHR5cGUgJXVc biIsIHR5cGUpOwo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+ICsgICAgICAg fQo+PiArICAgICAgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICt2b2lkIGhpYm1jX3R0bV9wbGFj ZW1lbnQoc3RydWN0IGhpYm1jX2JvICpibywgaW50IGRvbWFpbikKPj4gK3sKPj4gKyAgICAgICB1 MzIgYyA9IDA7Cj4KPiBDYW4geW91IHBsZWFzZSB1c2UgYSBtb3JlIGRlc2NyaXB0aXZlIG5hbWUg dGhhbiAnYyc/Cgpvaywgd2lsbCBkbyB0aGF0LgoKPgo+PiArICAgICAgIHUzMiBpOwo+PiArCj4+ ICsgICAgICAgYm8tPnBsYWNlbWVudC5wbGFjZW1lbnQgPSBiby0+cGxhY2VtZW50czsKPj4gKyAg ICAgICBiby0+cGxhY2VtZW50LmJ1c3lfcGxhY2VtZW50ID0gYm8tPnBsYWNlbWVudHM7Cj4+ICsg ICAgICAgaWYgKGRvbWFpbiAmIFRUTV9QTF9GTEFHX1ZSQU0pCj4+ICsgICAgICAgICAgICAgICBi by0+cGxhY2VtZW50c1tjKytdLmZsYWdzID0gVFRNX1BMX0ZMQUdfV0MgfAo+PiArICAgICAgICAg ICAgICAgVFRNX1BMX0ZMQUdfVU5DQUNIRUQgfCBUVE1fUExfRkxBR19WUkFNOwo+Cj4gbml0OiB5 b3UncmUgYWxpZ25tZW50IGlzIG9mZiBoZXJlIGFuZCBiZWxvdwoKaXMgaXQgY29ycmVjdD8KCglp ZiAoZG9tYWluICYgVFRNX1BMX0ZMQUdfVlJBTSkKCQliby0+cGxhY2VtZW50c1tjKytdLmZsYWdz ID0gVFRNX1BMX0ZMQUdfV0MgfAoJCQlUVE1fUExfRkxBR19VTkNBQ0hFRCB8IFRUTV9QTF9GTEFH X1ZSQU07CglpZiAoZG9tYWluICYgVFRNX1BMX0ZMQUdfU1lTVEVNKQoJCWJvLT5wbGFjZW1lbnRz W2MrK10uZmxhZ3MgPSBUVE1fUExfTUFTS19DQUNISU5HIHwKCQkJVFRNX1BMX0ZMQUdfU1lTVEVN OwoJaWYgKCFjKQoJCWJvLT5wbGFjZW1lbnRzW2MrK10uZmxhZ3MgPSBUVE1fUExfTUFTS19DQUNI SU5HIHwKCQkJVFRNX1BMX0ZMQUdfU1lTVEVNOwoKPgo+PiArICAgICAgIGlmIChkb21haW4gJiBU VE1fUExfRkxBR19TWVNURU0pCj4+ICsgICAgICAgICAgICAgICBiby0+cGxhY2VtZW50c1tjKytd LmZsYWdzID0gVFRNX1BMX01BU0tfQ0FDSElORyB8Cj4+ICsgICAgICAgICAgICAgICBUVE1fUExf RkxBR19TWVNURU07Cj4+ICsgICAgICAgaWYgKCFjKQo+PiArICAgICAgICAgICAgICAgYm8tPnBs YWNlbWVudHNbYysrXS5mbGFncyA9IFRUTV9QTF9NQVNLX0NBQ0hJTkcgfAo+PiArICAgICAgICAg ICAgICAgVFRNX1BMX0ZMQUdfU1lTVEVNOwo+PiArCj4+ICsgICAgICAgYm8tPnBsYWNlbWVudC5u dW1fcGxhY2VtZW50ID0gYzsKPj4gKyAgICAgICBiby0+cGxhY2VtZW50Lm51bV9idXN5X3BsYWNl bWVudCA9IGM7Cj4+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IGM7ICsraSkgewo+Cj4gbml0OiB3 ZSB0ZW5kIHRvd2FyZHMgcG9zdC1pbmNyZW1lbnQgaW4ga2VybmVsCgphZ3JlZWQsIHRoYW5rcy4K Cj4KPj4gKyAgICAgICAgICAgICAgIGJvLT5wbGFjZW1lbnRzW2ldLmZwZm4gPSAwOwo+PiArICAg ICAgICAgICAgICAgYm8tPnBsYWNlbWVudHNbaV0ubHBmbiA9IDA7Cj4+ICsgICAgICAgfQo+PiAr fQo+PiArCj4+ICtzdGF0aWMgdm9pZAo+PiAraGlibWNfYm9fZXZpY3RfZmxhZ3Moc3RydWN0IHR0 bV9idWZmZXJfb2JqZWN0ICpibywgc3RydWN0IHR0bV9wbGFjZW1lbnQgKnBsKQo+PiArewo+PiAr ICAgICAgIHN0cnVjdCBoaWJtY19ibyAqaGlibWNibyA9IGhpYm1jX2JvKGJvKTsKPj4gKwo+PiAr ICAgICAgIGlmICghaGlibWNfdHRtX2JvX2lzX2hpYm1jX2JvKGJvKSkKPj4gKyAgICAgICAgICAg ICAgIHJldHVybjsKPj4gKwo+PiArICAgICAgIGhpYm1jX3R0bV9wbGFjZW1lbnQoaGlibWNibywg VFRNX1BMX0ZMQUdfU1lTVEVNKTsKPj4gKyAgICAgICAqcGwgPSBoaWJtY2JvLT5wbGFjZW1lbnQ7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaGlibWNfYm9fdmVyaWZ5X2FjY2VzcyhzdHJ1Y3Qg dHRtX2J1ZmZlcl9vYmplY3QgKmJvLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc3RydWN0IGZpbGUgKmZpbHApCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2JvICpo aWJtY2JvID0gaGlibWNfYm8oYm8pOwo+PiArCj4+ICsgICAgICAgcmV0dXJuIGRybV92bWFfbm9k ZV92ZXJpZnlfYWNjZXNzKCZoaWJtY2JvLT5nZW0udm1hX25vZGUsCj4+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHAtPnByaXZhdGVfZGF0YSk7Cj4+ICt9Cj4+ ICsKPj4gK3N0YXRpYyBpbnQgaGlibWNfdHRtX2lvX21lbV9yZXNlcnZlKHN0cnVjdCB0dG1fYm9f ZGV2aWNlICpiZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1 Y3QgdHRtX21lbV9yZWcgKm1lbSkKPj4gK3sKPj4gKyAgICAgICBzdHJ1Y3QgdHRtX21lbV90eXBl X21hbmFnZXIgKm1hbiA9ICZiZGV2LT5tYW5bbWVtLT5tZW1fdHlwZV07Cj4+ICsgICAgICAgc3Ry dWN0IGhpYm1jX2RybV9kZXZpY2UgKmhpYm1jID0gaGlibWNfYmRldihiZGV2KTsKPj4gKwo+PiAr ICAgICAgIG1lbS0+YnVzLmFkZHIgPSBOVUxMOwo+PiArICAgICAgIG1lbS0+YnVzLm9mZnNldCA9 IDA7Cj4+ICsgICAgICAgbWVtLT5idXMuc2l6ZSA9IG1lbS0+bnVtX3BhZ2VzIDw8IFBBR0VfU0hJ RlQ7Cj4+ICsgICAgICAgbWVtLT5idXMuYmFzZSA9IDA7Cj4+ICsgICAgICAgbWVtLT5idXMuaXNf aW9tZW0gPSBmYWxzZTsKPj4gKyAgICAgICBpZiAoIShtYW4tPmZsYWdzICYgVFRNX01FTVRZUEVf RkxBR19NQVBQQUJMRSkpCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4gKyAg ICAgICBzd2l0Y2ggKG1lbS0+bWVtX3R5cGUpIHsKPj4gKyAgICAgICBjYXNlIFRUTV9QTF9TWVNU RU06Cj4+ICsgICAgICAgICAgICAgICAvKiBzeXN0ZW0gbWVtb3J5ICovCj4+ICsgICAgICAgICAg ICAgICByZXR1cm4gMDsKPj4gKyAgICAgICBjYXNlIFRUTV9QTF9WUkFNOgo+PiArICAgICAgICAg ICAgICAgbWVtLT5idXMub2Zmc2V0ID0gbWVtLT5zdGFydCA8PCBQQUdFX1NISUZUOwo+PiArICAg ICAgICAgICAgICAgbWVtLT5idXMuYmFzZSA9IHBjaV9yZXNvdXJjZV9zdGFydChoaWJtYy0+ZGV2 LT5wZGV2LCAwKTsKPj4gKyAgICAgICAgICAgICAgIG1lbS0+YnVzLmlzX2lvbWVtID0gdHJ1ZTsK Pj4gKyAgICAgICAgICAgICAgIGJyZWFrOwo+PiArICAgICAgIGRlZmF1bHQ6Cj4+ICsgICAgICAg ICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4gKyAgICAgICB9Cj4+ICsgICAgICAgcmV0dXJuIDA7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGhpYm1jX3R0bV9pb19tZW1fZnJlZShzdHJ1Y3Qg dHRtX2JvX2RldmljZSAqYmRldiwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHN0cnVjdCB0dG1fbWVtX3JlZyAqbWVtKQo+PiArewo+PiArfQo+Cj4gTm8gbmVlZCB0byBzdHVi IHRoaXMsIHRoZSBjYWxsZXIgZG9lcyBhIE5VTEwtY2hlY2sgYmVmb3JlIGludm9raW5nCgp3aWxs IGRlbGV0ZSBpdCwgdGhhbmtzLgoKPgo+PiArCj4+ICtzdGF0aWMgdm9pZCBoaWJtY190dG1fYmFj a2VuZF9kZXN0cm95KHN0cnVjdCB0dG1fdHQgKnR0KQo+PiArewo+PiArICAgICAgIHR0bV90dF9m aW5pKHR0KTsKPj4gKyAgICAgICBrZnJlZSh0dCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1 Y3QgdHRtX2JhY2tlbmRfZnVuYyBoaWJtY190dF9iYWNrZW5kX2Z1bmMgPSB7Cj4+ICsgICAgICAg LmRlc3Ryb3kgPSAmaGlibWNfdHRtX2JhY2tlbmRfZGVzdHJveSwKPj4gK307Cj4+ICsKPj4gK3N0 YXRpYyBzdHJ1Y3QgdHRtX3R0ICpoaWJtY190dG1fdHRfY3JlYXRlKHN0cnVjdCB0dG1fYm9fZGV2 aWNlICpiZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1 bnNpZ25lZCBsb25nIHNpemUsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHUzMiBwYWdlX2ZsYWdzLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBzdHJ1Y3QgcGFnZSAqZHVtbXlfcmVhZF9wYWdlKQo+PiArewo+PiArICAgICAg IHN0cnVjdCB0dG1fdHQgKnR0Owo+PiArCj4+ICsgICAgICAgdHQgPSBremFsbG9jKHNpemVvZigq dHQpLCBHRlBfS0VSTkVMKTsKPj4gKyAgICAgICBpZiAoIXR0KQo+Cj4gUHJpbnQgZXJyb3IKCm9r LCB3aWxsIGRvIHRoYXQsIHRoYW5rcy4KCj4KPj4gKyAgICAgICAgICAgICAgIHJldHVybiBOVUxM Owo+PiArICAgICAgIHR0LT5mdW5jID0gJmhpYm1jX3R0X2JhY2tlbmRfZnVuYzsKPj4gKyAgICAg ICBpZiAodHRtX3R0X2luaXQodHQsIGJkZXYsIHNpemUsIHBhZ2VfZmxhZ3MsIGR1bW15X3JlYWRf cGFnZSkpIHsKPgo+IEhlcmUgdG9vPwoKZGl0dG8KCj4KPj4gKyAgICAgICAgICAgICAgIGtmcmVl KHR0KTsKPj4gKyAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwo+PiArICAgICAgIH0KPj4gKyAg ICAgICByZXR1cm4gdHQ7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaGlibWNfdHRtX3R0X3Bv cHVsYXRlKHN0cnVjdCB0dG1fdHQgKnR0bSkKPj4gK3sKPj4gKyAgICAgICByZXR1cm4gdHRtX3Bv b2xfcG9wdWxhdGUodHRtKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgaGlibWNfdHRtX3R0 X3VucG9wdWxhdGUoc3RydWN0IHR0bV90dCAqdHRtKQo+PiArewo+PiArICAgICAgIHR0bV9wb29s X3VucG9wdWxhdGUodHRtKTsKPj4gK30KPj4gKwo+PiArc3RydWN0IHR0bV9ib19kcml2ZXIgaGli bWNfYm9fZHJpdmVyID0gewo+PiArICAgICAgIC50dG1fdHRfY3JlYXRlICAgICAgICAgID0gaGli bWNfdHRtX3R0X2NyZWF0ZSwKPj4gKyAgICAgICAudHRtX3R0X3BvcHVsYXRlICAgICAgICA9IGhp Ym1jX3R0bV90dF9wb3B1bGF0ZSwKPj4gKyAgICAgICAudHRtX3R0X3VucG9wdWxhdGUgICAgICA9 IGhpYm1jX3R0bV90dF91bnBvcHVsYXRlLAo+PiArICAgICAgIC5pbml0X21lbV90eXBlICAgICAg ICAgID0gaGlibWNfYm9faW5pdF9tZW1fdHlwZSwKPj4gKyAgICAgICAuZXZpY3RfZmxhZ3MgICAg ICAgICAgICA9IGhpYm1jX2JvX2V2aWN0X2ZsYWdzLAo+PiArICAgICAgIC5tb3ZlICAgICAgICAg ICAgICAgICAgID0gTlVMTCwKPj4gKyAgICAgICAudmVyaWZ5X2FjY2VzcyAgICAgICAgICA9IGhp Ym1jX2JvX3ZlcmlmeV9hY2Nlc3MsCj4+ICsgICAgICAgLmlvX21lbV9yZXNlcnZlICAgICAgICAg PSAmaGlibWNfdHRtX2lvX21lbV9yZXNlcnZlLAo+PiArICAgICAgIC5pb19tZW1fZnJlZSAgICAg ICAgICAgID0gJmhpYm1jX3R0bV9pb19tZW1fZnJlZSwKPj4gKyAgICAgICAubHJ1X3RhaWwgICAg ICAgICAgICAgICA9ICZ0dG1fYm9fZGVmYXVsdF9scnVfdGFpbCwKPj4gKyAgICAgICAuc3dhcF9s cnVfdGFpbCAgICAgICAgICA9ICZ0dG1fYm9fZGVmYXVsdF9zd2FwX2xydV90YWlsLAo+PiArfTsK Pj4gKwo+PiAraW50IGhpYm1jX21tX2luaXQoc3RydWN0IGhpYm1jX2RybV9kZXZpY2UgKmhpYm1j KQo+PiArewo+PiArICAgICAgIGludCByZXQ7Cj4+ICsgICAgICAgc3RydWN0IGRybV9kZXZpY2Ug KmRldiA9IGhpYm1jLT5kZXY7Cj4+ICsgICAgICAgc3RydWN0IHR0bV9ib19kZXZpY2UgKmJkZXYg PSAmaGlibWMtPnR0bS5iZGV2Owo+PiArCj4+ICsgICAgICAgcmV0ID0gaGlibWNfdHRtX2dsb2Jh bF9pbml0KGhpYm1jKTsKPj4gKyAgICAgICBpZiAocmV0KQo+PiArICAgICAgICAgICAgICAgcmV0 dXJuIHJldDsKPj4gKwo+PiArICAgICAgIHJldCA9IHR0bV9ib19kZXZpY2VfaW5pdCgmaGlibWMt PnR0bS5iZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWJtYy0+dHRt LmJvX2dsb2JhbF9yZWYucmVmLm9iamVjdCwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgJmhpYm1jX2JvX2RyaXZlciwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgZGV2LT5hbm9uX2lub2RlLT5pX21hcHBpbmcsCj4+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIERSTV9GSUxFX1BBR0VfT0ZGU0VULAo+PiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB0cnVlKTsKPj4gKyAgICAgICBpZiAocmV0KSB7Cj4KPiBDYWxsIGhpYm1jX3R0 bV9nbG9iYWxfcmVsZWFzZSBoZXJlPwoKYWdyZWVkLCB0aGFua3MgZm9yIHBvaW50aW5nIGl0IG91 dC4KCj4KPj4gKyAgICAgICAgICAgICAgIERSTV9FUlJPUigiRXJyb3IgaW5pdGlhbGlzaW5nIGJv IGRyaXZlcjsgJWRcbiIsIHJldCk7Cj4+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+PiAr ICAgICAgIH0KPj4gKwo+PiArICAgICAgIHJldCA9IHR0bV9ib19pbml0X21tKGJkZXYsIFRUTV9Q TF9WUkFNLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpYm1jLT5mYl9zaXplID4+ IFBBR0VfU0hJRlQpOwo+PiArICAgICAgIGlmIChyZXQpIHsKPgo+IENsZWFuIHVwIGhlcmUgYXMg d2VsbD8KCmRpdHRvCgo+Cj4+ICsgICAgICAgICAgICAgICBEUk1fRVJST1IoIkZhaWxlZCB0dG0g VlJBTSBpbml0OiAlZFxuIiwgcmV0KTsKPj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4+ ICsgICAgICAgfQo+PiArCj4+ICsgICAgICAgaGlibWMtPm1tX2luaXRlZCA9IHRydWU7Cj4+ICsg ICAgICAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3ZvaWQgaGlibWNfbW1fZmluaShzdHJ1Y3Qg aGlibWNfZHJtX2RldmljZSAqaGlibWMpCj4+ICt7Cj4+ICsgICAgICAgaWYgKCFoaWJtYy0+bW1f aW5pdGVkKQo+PiArICAgICAgICAgICAgICAgcmV0dXJuOwo+PiArCj4+ICsgICAgICAgdHRtX2Jv X2RldmljZV9yZWxlYXNlKCZoaWJtYy0+dHRtLmJkZXYpOwo+PiArICAgICAgIGhpYm1jX3R0bV9n bG9iYWxfcmVsZWFzZShoaWJtYyk7Cj4+ICsgICAgICAgaGlibWMtPm1tX2luaXRlZCA9IGZhbHNl Owo+PiArfQo+PiArCj4+ICtpbnQgaGlibWNfYm9fY3JlYXRlKHN0cnVjdCBkcm1fZGV2aWNlICpk ZXYsIGludCBzaXplLCBpbnQgYWxpZ24sCj4+ICsgICAgICAgICAgICAgICAgICAgdTMyIGZsYWdz LCBzdHJ1Y3QgaGlibWNfYm8gKipwaGlibWNibykKPj4gK3sKPj4gKyAgICAgICBzdHJ1Y3QgaGli bWNfZHJtX2RldmljZSAqaGlibWMgPSBkZXYtPmRldl9wcml2YXRlOwo+PiArICAgICAgIHN0cnVj dCBoaWJtY19ibyAqaGlibWNibzsKPj4gKyAgICAgICBzaXplX3QgYWNjX3NpemU7Cj4+ICsgICAg ICAgaW50IHJldDsKPj4gKwo+PiArICAgICAgIGhpYm1jYm8gPSBremFsbG9jKHNpemVvZigqaGli bWNibyksIEdGUF9LRVJORUwpOwo+PiArICAgICAgIGlmICghaGlibWNibykKPj4gKyAgICAgICAg ICAgICAgIHJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsgICAgICAgcmV0ID0gZHJtX2dlbV9vYmpl Y3RfaW5pdChkZXYsICZoaWJtY2JvLT5nZW0sIHNpemUpOwo+PiArICAgICAgIGlmIChyZXQpIHsK Pj4gKyAgICAgICAgICAgICAgIGtmcmVlKGhpYm1jYm8pOwo+PiArICAgICAgICAgICAgICAgcmV0 dXJuIHJldDsKPj4gKyAgICAgICB9Cj4+ICsKPj4gKyAgICAgICBoaWJtY2JvLT5iby5iZGV2ID0g JmhpYm1jLT50dG0uYmRldjsKPj4gKwo+PiArICAgICAgIGhpYm1jX3R0bV9wbGFjZW1lbnQoaGli bWNibywgVFRNX1BMX0ZMQUdfVlJBTSB8IFRUTV9QTF9GTEFHX1NZU1RFTSk7Cj4+ICsKPj4gKyAg ICAgICBhY2Nfc2l6ZSA9IHR0bV9ib19kbWFfYWNjX3NpemUoJmhpYm1jLT50dG0uYmRldiwgc2l6 ZSwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVj dCBoaWJtY19ibykpOwo+PiArCj4+ICsgICAgICAgcmV0ID0gdHRtX2JvX2luaXQoJmhpYm1jLT50 dG0uYmRldiwgJmhpYm1jYm8tPmJvLCBzaXplLAo+PiArICAgICAgICAgICAgICAgICAgICAgICAg IHR0bV9ib190eXBlX2RldmljZSwgJmhpYm1jYm8tPnBsYWNlbWVudCwKPj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICBhbGlnbiA+PiBQQUdFX1NISUZULCBmYWxzZSwgTlVMTCwgYWNjX3NpemUs Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgaGlibWNfYm9fdHRtX2Rl c3Ryb3kpOwo+PiArICAgICAgIGlmIChyZXQpCj4KPiBNaXNzaW5nIGhpYm1jYm8gY2xlYW4gdXAg aGVyZQoKaSBsb29rZWQgYXQgYWxsIG90aGVyIHR0bSBkcml2ZXJzIGFuZCBhbGwgb2YgdGhlbSBy ZXR1cm4gZGlyZWN0bHkgd2hlbiB0dG1fYm9faW5pdApmYWlsZWQsIGhvd2V2ZXIsIGkgdGhpbmsg aXQgaXMgYmV0dGVyIHRvIGNsZWFuIHVwIGhlcmUsIHNob3VsZCBpIGNhbGwKaGlibWNfYm9fdW5y ZWYoJmhpYm1jX2JvKSBoZXJlID8KCj4KPj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4+ ICsKPj4gKyAgICAgICAqcGhpYm1jYm8gPSBoaWJtY2JvOwo+PiArICAgICAgIHJldHVybiAwOwo+ PiArfQo+PiArCj4+ICtzdGF0aWMgaW5saW5lIHU2NCBoaWJtY19ib19ncHVfb2Zmc2V0KHN0cnVj dCBoaWJtY19ibyAqYm8pCj4+ICt7Cj4+ICsgICAgICAgcmV0dXJuIGJvLT5iby5vZmZzZXQ7Cj4+ ICt9Cj4KPiBJIGRvbid0IHRoaW5rIHRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgYW55IHZhbHVlCgpk byB5b3UgbmVhbiBpIHVzZSBiby0+Ym8ub2Zmc2V0IGluc3RlYWQgb2YgY2FsbGluZyBoaWJtY19i b19ncHVfb2Zmc2V0KCk/Cgo+Cj4+ICsKPj4gK2ludCBoaWJtY19ib19waW4oc3RydWN0IGhpYm1j X2JvICpibywgdTMyIHBsX2ZsYWcsIHU2NCAqZ3B1X2FkZHIpCj4+ICt7Cj4+ICsgICAgICAgaW50 IGksIHJldDsKPj4gKwo+PiArICAgICAgIGlmIChiby0+cGluX2NvdW50KSB7Cj4+ICsgICAgICAg ICAgICAgICBiby0+cGluX2NvdW50Kys7Cj4+ICsgICAgICAgICAgICAgICBpZiAoZ3B1X2FkZHIp Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgICpncHVfYWRkciA9IGhpYm1jX2JvX2dwdV9vZmZz ZXQoYm8pOwo+Cj4gQXJlIHlvdSBtaXNzaW5nIGEgcmV0dXJuIGhlcmU/CgpUaGFua3MgZm9yIHBv aW50aW5nIGl0IG91dCEKCj4KPj4gKyAgICAgICB9Cj4+ICsKPj4gKyAgICAgICBoaWJtY190dG1f cGxhY2VtZW50KGJvLCBwbF9mbGFnKTsKPj4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgYm8tPnBs YWNlbWVudC5udW1fcGxhY2VtZW50OyBpKyspCj4+ICsgICAgICAgICAgICAgICBiby0+cGxhY2Vt ZW50c1tpXS5mbGFncyB8PSBUVE1fUExfRkxBR19OT19FVklDVDsKPj4gKyAgICAgICByZXQgPSB0 dG1fYm9fdmFsaWRhdGUoJmJvLT5ibywgJmJvLT5wbGFjZW1lbnQsIGZhbHNlLCBmYWxzZSk7Cj4+ ICsgICAgICAgaWYgKHJldCkKPj4gKyAgICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4+ICsKPj4g KyAgICAgICBiby0+cGluX2NvdW50ID0gMTsKPj4gKyAgICAgICBpZiAoZ3B1X2FkZHIpCj4+ICsg ICAgICAgICAgICAgICAqZ3B1X2FkZHIgPSBoaWJtY19ib19ncHVfb2Zmc2V0KGJvKTsKPj4gKyAg ICAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiAraW50IGhpYm1jX2JvX3B1c2hfc3lzcmFtKHN0 cnVjdCBoaWJtY19ibyAqYm8pCj4+ICt7Cj4+ICsgICAgICAgaW50IGksIHJldDsKPj4gKwo+PiAr ICAgICAgIGlmICghYm8tPnBpbl9jb3VudCkgewo+PiArICAgICAgICAgICAgICAgRFJNX0VSUk9S KCJ1bnBpbiBiYWQgJXBcbiIsIGJvKTsKPj4gKyAgICAgICAgICAgICAgIHJldHVybiAwOwo+PiAr ICAgICAgIH0KPj4gKyAgICAgICBiby0+cGluX2NvdW50LS07Cj4+ICsgICAgICAgaWYgKGJvLT5w aW5fY291bnQpCj4+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPj4gKwo+PiArICAgICAgIGlm IChiby0+a21hcC52aXJ0dWFsKQo+Cj4gdHRtX2JvX2t1bm1hcCBhbHJlYWR5IGRvZXMgdGhpcyBj aGVjayBzbyB5b3UgZG9uJ3QgaGF2ZSB0bwoKYWdyZWVkLiB3aWxsIHJlbW92ZSB0aGlzIGNvbmRp dGlvbi4KCj4KPj4gKyAgICAgICAgICAgICAgIHR0bV9ib19rdW5tYXAoJmJvLT5rbWFwKTsKPj4g Kwo+PiArICAgICAgIGhpYm1jX3R0bV9wbGFjZW1lbnQoYm8sIFRUTV9QTF9GTEFHX1NZU1RFTSk7 Cj4+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IGJvLT5wbGFjZW1lbnQubnVtX3BsYWNlbWVudCA7 IGkrKykKPj4gKyAgICAgICAgICAgICAgIGJvLT5wbGFjZW1lbnRzW2ldLmZsYWdzIHw9IFRUTV9Q TF9GTEFHX05PX0VWSUNUOwo+PiArCj4+ICsgICAgICAgcmV0ID0gdHRtX2JvX3ZhbGlkYXRlKCZi by0+Ym8sICZiby0+cGxhY2VtZW50LCBmYWxzZSwgZmFsc2UpOwo+PiArICAgICAgIGlmIChyZXQp IHsKPj4gKyAgICAgICAgICAgICAgIERSTV9FUlJPUigicHVzaGluZyB0byBWUkFNIGZhaWxlZFxu Iik7Cj4KPiBQcmludCByZXQKCm9rLCB0aGFua3MuCgo+Cj4+ICsgICAgICAgICAgICAgICByZXR1 cm4gcmV0Owo+PiArICAgICAgIH0KPj4gKyAgICAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiAr aW50IGhpYm1jX21tYXAoc3RydWN0IGZpbGUgKmZpbHAsIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAq dm1hKQo+PiArewo+PiArICAgICAgIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2Owo+PiArICAg ICAgIHN0cnVjdCBoaWJtY19kcm1fZGV2aWNlICpoaWJtYzsKPj4gKwo+PiArICAgICAgIGlmICh1 bmxpa2VseSh2bWEtPnZtX3Bnb2ZmIDwgRFJNX0ZJTEVfUEFHRV9PRkZTRVQpKQo+PiArICAgICAg ICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+ICsKPj4gKyAgICAgICBmaWxlX3ByaXYgPSBmaWxw LT5wcml2YXRlX2RhdGE7Cj4+ICsgICAgICAgaGlibWMgPSBmaWxlX3ByaXYtPm1pbm9yLT5kZXYt PmRldl9wcml2YXRlOwo+PiArICAgICAgIHJldHVybiB0dG1fYm9fbW1hcChmaWxwLCB2bWEsICZo aWJtYy0+dHRtLmJkZXYpOwo+PiArfQo+PiArCj4+ICtpbnQgaGlibWNfZ2VtX2NyZWF0ZShzdHJ1 Y3QgZHJtX2RldmljZSAqZGV2LCB1MzIgc2l6ZSwgYm9vbCBpc2tlcm5lbCwKPj4gKyAgICAgICAg ICAgICAgICAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICoqb2JqKQo+PiArewo+PiArICAgICAg IHN0cnVjdCBoaWJtY19ibyAqaGlibWNibzsKPj4gKyAgICAgICBpbnQgcmV0Owo+PiArCj4+ICsg ICAgICAgKm9iaiA9IE5VTEw7Cj4+ICsKPj4gKyAgICAgICBzaXplID0gUEFHRV9BTElHTihzaXpl KTsKPj4gKyAgICAgICBpZiAoc2l6ZSA9PSAwKQo+Cj4gUHJpbnQgZXJyb3IKCmRpdHRvCgo+Cj4+ ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPj4gKwo+PiArICAgICAgIHJldCA9IGhp Ym1jX2JvX2NyZWF0ZShkZXYsIHNpemUsIDAsIDAsICZoaWJtY2JvKTsKPj4gKyAgICAgICBpZiAo cmV0KSB7Cj4+ICsgICAgICAgICAgICAgICBpZiAocmV0ICE9IC1FUkVTVEFSVFNZUykKPj4gKyAg ICAgICAgICAgICAgICAgICAgICAgRFJNX0VSUk9SKCJmYWlsZWQgdG8gYWxsb2NhdGUgR0VNIG9i amVjdFxuIik7Cj4KPiBQcmludCByZXQKCmRpdHRvCgo+Cj4+ICsgICAgICAgICAgICAgICByZXR1 cm4gcmV0Owo+PiArICAgICAgIH0KPj4gKyAgICAgICAqb2JqID0gJmhpYm1jYm8tPmdlbTsKPj4g KyAgICAgICByZXR1cm4gMDsKPj4gK30KPj4gKwo+PiAraW50IGhpYm1jX2R1bWJfY3JlYXRlKHN0 cnVjdCBkcm1fZmlsZSAqZmlsZSwgc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gKyAgICAgICAg ICAgICAgICAgICAgIHN0cnVjdCBkcm1fbW9kZV9jcmVhdGVfZHVtYiAqYXJncykKPj4gK3sKPj4g KyAgICAgICBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKmdvYmo7Cj4+ICsgICAgICAgdTMyIGhhbmRs ZTsKPj4gKyAgICAgICBpbnQgcmV0Owo+PiArCj4+ICsgICAgICAgYXJncy0+cGl0Y2ggPSBBTElH TihhcmdzLT53aWR0aCAqICgoYXJncy0+YnBwICsgNykgLyA4KSwgMTYpOwo+Cj4gV2hhdCdzIHVw IHdpdGggdGhlIGJwcCArIDcgaGVyZT8gUGVyaGFwcyB5b3UncmUgbG9va2luZyBmb3IgRElWX1JP VU5EX1VQPwoKWWVzLCB0aGF0IHNvdW5kcyBzYW5lLgoKPgo+Cj4+ICsgICAgICAgYXJncy0+c2l6 ZSA9IGFyZ3MtPnBpdGNoICogYXJncy0+aGVpZ2h0Owo+PiArCj4+ICsgICAgICAgcmV0ID0gaGli bWNfZ2VtX2NyZWF0ZShkZXYsIGFyZ3MtPnNpemUsIGZhbHNlLAo+PiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgJmdvYmopOwo+PiArICAgICAgIGlmIChyZXQpCj4+ICsgICAgICAgICAg ICAgICByZXR1cm4gcmV0Owo+PiArCj4+ICsgICAgICAgcmV0ID0gZHJtX2dlbV9oYW5kbGVfY3Jl YXRlKGZpbGUsIGdvYmosICZoYW5kbGUpOwo+PiArICAgICAgIGRybV9nZW1fb2JqZWN0X3VucmVm ZXJlbmNlX3VubG9ja2VkKGdvYmopOwo+PiArICAgICAgIGlmIChyZXQpCj4KPiBQcmludCBlcnJv ciBoZXJlCgphZ3JlZWQuCgo+Cj4+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+PiArCj4+ ICsgICAgICAgYXJncy0+aGFuZGxlID0gaGFuZGxlOwo+PiArICAgICAgIHJldHVybiAwOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgdm9pZCBoaWJtY19ib191bnJlZihzdHJ1Y3QgaGlibWNfYm8gKipi bykKPj4gK3sKPj4gKyAgICAgICBzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QgKnRibzsKPj4gKwo+ PiArICAgICAgIGlmICgoKmJvKSA9PSBOVUxMKQo+PiArICAgICAgICAgICAgICAgcmV0dXJuOwo+ PiArCj4+ICsgICAgICAgdGJvID0gJigoKmJvKS0+Ym8pOwo+PiArICAgICAgIHR0bV9ib191bnJl ZigmdGJvKTsKPj4gKyAgICAgICAqYm8gPSBOVUxMOwo+PiArfQo+PiArCj4+ICt2b2lkIGhpYm1j X2dlbV9mcmVlX29iamVjdChzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaikKPj4gK3sKPj4gKyAg ICAgICBzdHJ1Y3QgaGlibWNfYm8gKmhpYm1jYm8gPSBnZW1fdG9faGlibWNfYm8ob2JqKTsKPj4g Kwo+PiArICAgICAgIGhpYm1jX2JvX3VucmVmKCZoaWJtY2JvKTsKPj4gK30KPj4gKwo+PiArc3Rh dGljIHU2NCBoaWJtY19ib19tbWFwX29mZnNldChzdHJ1Y3QgaGlibWNfYm8gKmJvKQo+PiArewo+ PiArICAgICAgIHJldHVybiBkcm1fdm1hX25vZGVfb2Zmc2V0X2FkZHIoJmJvLT5iby52bWFfbm9k ZSk7Cj4+ICt9Cj4+ICsKPj4gK2ludCBoaWJtY19kdW1iX21tYXBfb2Zmc2V0KHN0cnVjdCBkcm1f ZmlsZSAqZmlsZSwgc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgdTMyIGhhbmRsZSwgdTY0ICpvZmZzZXQpCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0 IGRybV9nZW1fb2JqZWN0ICpvYmo7Cj4+ICsgICAgICAgc3RydWN0IGhpYm1jX2JvICpibzsKPj4g Kwo+PiArICAgICAgIG9iaiA9IGRybV9nZW1fb2JqZWN0X2xvb2t1cChmaWxlLCBoYW5kbGUpOwo+ PiArICAgICAgIGlmICghb2JqKQo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTk9FTlQ7Cj4+ ICsKPj4gKyAgICAgICBibyA9IGdlbV90b19oaWJtY19ibyhvYmopOwo+PiArICAgICAgICpvZmZz ZXQgPSBoaWJtY19ib19tbWFwX29mZnNldChibyk7Cj4+ICsKPj4gKyAgICAgICBkcm1fZ2VtX29i amVjdF91bnJlZmVyZW5jZV91bmxvY2tlZChvYmopOwo+PiArICAgICAgIHJldHVybiAwOwo+PiAr fQoKUmVnYXJkcywKUm9uZ3JvbmcuCgo+PiAtLQo+PiAxLjkuMQo+Pgo+Pgo+PiBfX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+PiBsaW51eC1hcm0ta2VybmVs IG1haWxpbmcgbGlzdAo+PiBsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKPj4g aHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2Vy bmVsCj4gX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPiBs aW51eGFybSBtYWlsaW5nIGxpc3QKPiBsaW51eGFybUBodWF3ZWkuY29tCj4gaHR0cDovL3JuZC1v cGVuZXVsZXIuaHVhd2VpLmNvbS9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4YXJtCj4KPiAuCj4KCgpf X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0t a2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcK aHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2Vy bmVsCg==