From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7F6F0C369CB for ; Wed, 23 Apr 2025 17:40:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=zlz9+lXXXq5LpAp/4W0Y5/tE7ySOCvZsvAQ3hIS8LwM=; b=yvGxiHRu69B7ywhKkfygof7qNU 1b96tbA8DfSL3RC3XvWH6WrKU4OsnVS2tDlx7RLRYuyPr/9a4qkIBTP6zCkVD8NhM07jnWqv5ASF8 ganHd00rCZwKUDnG9dgfwckKxbA4kk+GWJ7gEnyU+ZR35d1RqANOK2jjYlTsl60Tu+ilywAL9mqeu WuiIKVyNGOvhfDvt0Sa6ZQu7oqwdZeCKRVoVkTmXx/tzBYrcyNICBYwYGpJ+02lJDR3s4UH3uqLEp tPLNw/fo+3oCbXeQrePkZejyhcr5qsxsoNjAt3Uf4cgUs1I9tBZSoj9iZKQvedwGVkYyWX9ROP6oh FTpwu6OA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u7e5G-0000000BILh-3iw2; Wed, 23 Apr 2025 17:40:30 +0000 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1u7GOw-00000007tHA-1Qup; Tue, 22 Apr 2025 16:23:16 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 8806D43C8D; Tue, 22 Apr 2025 16:23:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44630C4CEE9; Tue, 22 Apr 2025 16:23:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1745338993; bh=5SXVdgY6N49lH5/liRgjfb+Iad1OUbcV8YvCE7OJPxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aWHx8aicB9liJT7yMTV96S9x9MRWP+DJAstSe+KRAODUCgEiLT7KNnH36FAkHDyBr Afqxm+kaTcZ+sN0Q4FEb30CFZ4A0E5ZL/rtSkVO4254LgJvklMkX9QYA6Djz3fF3z8 oU2abAu40pVZj1vGctPuqjTQvj+SlUya03S5wr5T1SY0qeHC+YBk02znxx0Tm7hHPa g5MRfL0XUGtuI71jTBQ5dsLnVOx0kElTijmESnWw/vQzFoWk98YLOJUrzcwP2qRZvg J6LxH/IKNmkcnq+2csnoN4tD5FGTCIRfrVf/akE1+m0JDL+yEOa4DloW/y9y2vmUZ+ xPJTmBWQkWkag== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Simon Horman , Simon Horman , Nick Kossifidis , Song Shuai , Li Zhengyu , kexec@lists.infradead.org Cc: Dave Young , Yixun Lan , Xianting Tian , linux-riscv@lists.infradead.org, =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Subject: [PATCH v2 1/4] RISC-V: Add support for riscv kexec/kdump on kexec-tools Date: Tue, 22 Apr 2025 18:22:57 +0200 Message-ID: <20250422162304.169431-2-bjorn@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250422162304.169431-1-bjorn@kernel.org> References: <20250422162304.169431-1-bjorn@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250422_092314_490498_C77D21DC X-CRM114-Status: GOOD ( 37.90 ) X-Mailman-Approved-At: Wed, 23 Apr 2025 08:14:49 -0700 X-BeenThere: kexec@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kexec" Errors-To: kexec-bounces+kexec=archiver.kernel.org@lists.infradead.org From: Nick Kossifidis This patch adds support for loading the ELF kernel image. It parses the current/provided device tree to determine the system's memory layout, and /proc/iomem for the various kernel segments. Tested on Qemu's rv64 virt machine and SoC of T-Head RISC-V Xuantie 910 CPU. Now, some history: The first stab at supporting kexec-tools on RISC-V was done by Nick Kossifidis. The initial patch has since then had a number of improvements/fixes by other authors. Given, this is the first commit for RISC-V, carrying the fixes/changes commits in the upstream tree does not really add anything (bisectability). Instead all the fixes that were applied to Nick's first commit is outlined below: Yixun Lan, and Xianting Tian: * Fixed a failure to fail to find free memory area for dtb load when using initrd image [1]. * Fixed memory range size calculation in kexec/arch/riscv/crashdump-riscv.c:85 Simon Horman: * workflow: Add riscv64 Add riscv64 to matrix of build architectures. * RISC-V: distribute purgatory/riscv/Makefile Include purgatory/riscv/Makefile in distribution tarball. Local patch as it is planned to suggest this as a fix for the patch that introduced this problem. [2] Song Shuai: * RISC-V: Fix the undeclared ‘EM_RISCV’ build failure Use local `elf.h` instead of `linux/elf.h` to fix this build error: ``` kexec/arch/riscv/crashdump-riscv.c:17:13: error: ‘EM_RISCV’ undeclared here (not in a function); did you mean ‘EM_CRIS’? .machine = EM_RISCV, ^~~~~~~~ EM_CRIS ``` * RISC-V: Correct the usage of command line option RISC-V process OPT_CMDLINE with the "command-line" partten, but the riscv_opts_usage shows the "cmdline" option. So correct the usage's output. * RISC-V: Use linux,usable-memory-range for crash kernel Now we use "memeory::linux,usable-memory" to indicate the available memory for the crash kernel. While booting with UEFI, the crash kernel would use efi.memmap to re-populate memblock and then first kernel's memory would be corrputed. Consequently, the /proc/vmcore file failed to create in my local test. And according to "chosen" dtschema [3], the available memory for the crash kernel should be held via "chosen::linux,usable-memory-range" property which will re-cap memblock even after UEFI's re-population. * RISC-V: Get memory ranges from iomem When booting with UEFI, Linux marks the Runtime Code/Data memory as no-map and then exports it to "Reserved" iomem_resource. Kexc-tools uses dtb_get_memory_ranges() function to get memory ranges via parsing dtb, but it can't see the Reserved EFI Runtime memory. That would corrupt EFI Runtime memory and fail the kexeced kernel to deal EFI stuff. In my test, the kexeced kernel warned "efi: System table signature incorrect!" and then paniced at efi_call_rts() due to the null efi.runtime. So we should use /proc/iomem to get memory ranges. Björn Töpel: * Massaged this commit message! * Fixed up the build, by adding missing RV stub. * RISC-V: Only cap the upper/end usable memory window When loading the initrd in the kexec_load flow, memory for the segments are searched from end to start. Only the max_usable should be capped, after a successful initrd addtion. Currently min/max usable is set to the same value, making it impossible from subsequent segment allocations to success. * RISC-V: Make get_memory_ranges() properly exclude "Reserved" regions The get_memory_ranges() did not exclude "Reserved" regions from "System RAM" regions. It simply added "Reserved" as IOMEM, and IOMEM is not considered when looking for holes to place kexec segments. Instead, do a two pass of the /proc/iomem file. First pass, adds all the "System RAM" memory, and the second pass removes all intersecting "Reserved" regions. [1] https://lore.kernel.org/linux-riscv/CALecT5gQWn0PRO4Q24b6qkrfVE5OxsCp65TuhWTb30ceK_OJ0A@mail.gmail.com/ [2] https://lore.kernel.org/kexec/20221020031548.47587-1-xianting.tian@linux.alibaba.com/ [3] https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/chosen.yaml Tested-by: Yixun Lan Co-developed-by: Xianting Tian Co-developed-by: Yixun Lan Signed-off-by: Nick Kossifidis Signed-off-by: Simon Horman Signed-off-by: Song Shuai Signed-off-by: Björn Töpel --- .github/workflows/build.yml | 1 + configure.ac | 3 + include/elf.h | 1 + kexec/Makefile | 1 + kexec/arch/mips/Makefile | 2 + kexec/arch/riscv/Makefile | 36 ++ kexec/arch/riscv/crashdump-riscv.c | 140 ++++++++ kexec/arch/riscv/include/arch/options.h | 43 +++ kexec/arch/riscv/iomem.h | 10 + kexec/arch/riscv/kexec-elf-riscv.c | 255 ++++++++++++++ kexec/arch/riscv/kexec-riscv.c | 431 +++++++++++++++++++++++ kexec/arch/riscv/kexec-riscv.h | 32 ++ kexec/dt-ops.c | 442 +++++++++++++++++++++++- kexec/dt-ops.h | 7 + kexec/kexec-syscall.h | 4 + purgatory/Makefile | 1 + purgatory/arch/riscv/Makefile | 7 + 17 files changed, 1415 insertions(+), 1 deletion(-) create mode 100644 kexec/arch/riscv/Makefile create mode 100644 kexec/arch/riscv/crashdump-riscv.c create mode 100644 kexec/arch/riscv/include/arch/options.h create mode 100644 kexec/arch/riscv/iomem.h create mode 100644 kexec/arch/riscv/kexec-elf-riscv.c create mode 100644 kexec/arch/riscv/kexec-riscv.c create mode 100644 kexec/arch/riscv/kexec-riscv.h create mode 100644 purgatory/arch/riscv/Makefile diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 46edde66e384..ddb4bfa8b01d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,6 +19,7 @@ jobs: - powerpc - powerpc64 - powerpc64le + - riscv64 - sh4 - s390x - x86_64-x32 diff --git a/configure.ac b/configure.ac index 8b79eef9afeb..cbd6edbd987d 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,9 @@ case $target_cpu in loongarch*) ARCH="loongarch" ;; + riscv32|riscv64) + ARCH="riscv" + ;; * ) AC_MSG_ERROR([unsupported architecture $target_cpu]) ;; diff --git a/include/elf.h b/include/elf.h index 1c8d2ccf6d26..93a5ee5eeffa 100644 --- a/include/elf.h +++ b/include/elf.h @@ -259,6 +259,7 @@ typedef struct #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_AARCH64 183 /* ARM AARCH64 */ +#define EM_RISCV 243 /* RISC-V */ #define EM_LOONGARCH 258 /* Loongson Loongarch*/ #define EM_NUM 184 diff --git a/kexec/Makefile b/kexec/Makefile index e969d1e18c5a..8b5851decaea 100644 --- a/kexec/Makefile +++ b/kexec/Makefile @@ -92,6 +92,7 @@ include $(srcdir)/kexec/arch/mips/Makefile include $(srcdir)/kexec/arch/cris/Makefile include $(srcdir)/kexec/arch/ppc/Makefile include $(srcdir)/kexec/arch/ppc64/Makefile +include $(srcdir)/kexec/arch/riscv/Makefile include $(srcdir)/kexec/arch/s390/Makefile include $(srcdir)/kexec/arch/sh/Makefile include $(srcdir)/kexec/arch/x86_64/Makefile diff --git a/kexec/arch/mips/Makefile b/kexec/arch/mips/Makefile index 1fe788608fbe..0a5ce1926dc9 100644 --- a/kexec/arch/mips/Makefile +++ b/kexec/arch/mips/Makefile @@ -13,6 +13,8 @@ mips_FS2DT_INCLUDE = \ mips_DT_OPS += kexec/dt-ops.c +mips_MEM_REGIONS = kexec/mem_regions.c + include $(srcdir)/kexec/libfdt/Makefile.libfdt libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) diff --git a/kexec/arch/riscv/Makefile b/kexec/arch/riscv/Makefile new file mode 100644 index 000000000000..9937fbb5724f --- /dev/null +++ b/kexec/arch/riscv/Makefile @@ -0,0 +1,36 @@ +# +# kexec riscv +# +riscv_KEXEC_SRCS = kexec/arch/riscv/crashdump-riscv.c +riscv_KEXEC_SRCS += kexec/arch/riscv/kexec-elf-riscv.c +riscv_KEXEC_SRCS += kexec/arch/riscv/kexec-riscv.c + +riscv_DT_OPS += kexec/dt-ops.c + +riscv_MEM_REGIONS = kexec/mem_regions.c + +riscv_ARCH_REUSE_INITRD = + +riscv_CPPFLAGS += -I $(srcdir)/kexec/ + +dist += $(riscv_KEXEC_SRCS) \ + kexec/arch/riscv/include/arch/options.h \ + kexec/arch/riscv/iomem.h \ + kexec/arch/riscv/kexec-riscv.h \ + kexec/arch/riscv/Makefile + +ifdef HAVE_LIBFDT + +LIBS += -lfdt + +else + +include $(srcdir)/kexec/libfdt/Makefile.libfdt + +libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) + +riscv_CPPFLAGS += -I$(srcdir)/kexec/libfdt + +riscv_KEXEC_SRCS += $(libfdt_SRCS) + +endif diff --git a/kexec/arch/riscv/crashdump-riscv.c b/kexec/arch/riscv/crashdump-riscv.c new file mode 100644 index 000000000000..336d7a7f5646 --- /dev/null +++ b/kexec/arch/riscv/crashdump-riscv.c @@ -0,0 +1,140 @@ +#include +#include +#include + +#include "kexec.h" +#include "crashdump.h" +#include "kexec-elf.h" +#include "mem_regions.h" + +static struct crash_elf_info elf_info = { +#if __riscv_xlen == 64 + .class = ELFCLASS64, +#else + .class = ELFCLASS32, +#endif + .data = ELFDATA2LSB, + .machine = EM_RISCV, +}; + +static struct memory_ranges crash_mem_ranges = {0}; +struct memory_range elfcorehdr_mem = {0}; + +static unsigned long long get_page_offset(struct kexec_info *info) +{ + unsigned long long vaddr_off = 0; + unsigned long long page_size = sysconf(_SC_PAGESIZE); + unsigned long long init_start = get_kernel_sym("_sinittext"); + + /* + * Begining of init section is aligned to page size + */ + vaddr_off = init_start - page_size; + + return vaddr_off; +} + +int load_elfcorehdr(struct kexec_info *info) +{ + struct memory_range crashkern_range = {0}; + struct memory_range *ranges = NULL; + unsigned long start = 0; + unsigned long end = 0; + unsigned long buf_size = 0; + unsigned long elfcorehdr_addr = 0; + void* buf = NULL; + int i = 0; + int ret = 0; + + ret = parse_iomem_single("Kernel code\n", &start, NULL); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical base addr\n"); + return -EINVAL; + } + elf_info.kern_paddr_start = start; + + ret = parse_iomem_single("Kernel bss\n", NULL, &end); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical bss addr\n"); + return -EINVAL; + } + elf_info.kern_paddr_start = start; + elf_info.kern_size = end - start; + + elf_info.kern_vaddr_start = get_kernel_sym("_text"); + if (!elf_info.kern_vaddr_start) { + elf_info.kern_vaddr_start = UINT64_MAX; + } + + elf_info.page_offset = get_page_offset(info); + dbgprintf("page_offset: %016llx\n", elf_info.page_offset); + + ret = parse_iomem_single("Crash kernel\n", &start, &end); + if (ret) { + fprintf(stderr, "Cannot determine kernel physical bss addr\n"); + return -EINVAL; + } + crashkern_range.start = start; + crashkern_range.end = end; + crashkern_range.type = RANGE_RESERVED; + + ranges = info->memory_range; + for (i = 0; i < info->memory_ranges; i++) { + ret = mem_regions_alloc_and_add(&crash_mem_ranges, + ranges[i].start, + ranges[i].end - ranges[i].start + 1, + ranges[i].type); + if (ret ) { + fprintf(stderr, "Could not create crash_mem_ranges\n"); + return ret; + } + } + + ret = mem_regions_alloc_and_exclude(&crash_mem_ranges, + &crashkern_range); + if (ret) { + fprintf(stderr, "Could not exclude crashkern_range\n"); + return ret; + } + +#if __riscv_xlen == 64 + crash_create_elf64_headers(info, &elf_info, crash_mem_ranges.ranges, + crash_mem_ranges.size, &buf, &buf_size, + ELF_CORE_HEADER_ALIGN); + +#else + crash_create_elf32_headers(info, &elf_info, crash_mem_ranges.ranges, + crash_mem_ranges.size, &buf, &buf_size, + ELF_CORE_HEADER_ALIGN); +#endif + + + elfcorehdr_addr = add_buffer_phys_virt(info, buf, buf_size, + buf_size, 0, + crashkern_range.start, + crashkern_range.end, + -1, 0); + + elfcorehdr_mem.start = elfcorehdr_addr; + elfcorehdr_mem.end = elfcorehdr_addr + buf_size - 1; + + dbgprintf("%s: elfcorehdr 0x%llx-0x%llx\n", __func__, + elfcorehdr_mem.start, elfcorehdr_mem.end); + + return 0; +} + +int is_crashkernel_mem_reserved(void) +{ + uint64_t start = 0; + uint64_t end = 0; + + return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ? + (start != end) : 0; +} + +int get_crash_kernel_load_range(uint64_t *start, uint64_t *end) +{ + return parse_iomem_single("Crash kernel\n", start, end); +} + diff --git a/kexec/arch/riscv/include/arch/options.h b/kexec/arch/riscv/include/arch/options.h new file mode 100644 index 000000000000..7c24184b1f3e --- /dev/null +++ b/kexec/arch/riscv/include/arch/options.h @@ -0,0 +1,43 @@ +#ifndef KEXEC_ARCH_RISCV_OPTIONS_H +#define KEXEC_ARCH_RISCV_OPTIONS_H + +#define OPT_APPEND ((OPT_MAX)+0) +#define OPT_DTB ((OPT_MAX)+1) +#define OPT_INITRD ((OPT_MAX)+2) +#define OPT_CMDLINE ((OPT_MAX)+3) +#define OPT_REUSE_CMDLINE ((OPT_MAX)+4) +#define OPT_ARCH_MAX ((OPT_MAX)+5) + +/* Options relevant to the architecture (excluding loader-specific ones), + * in this case none: + */ +#define KEXEC_ARCH_OPTIONS \ + KEXEC_OPTIONS \ + { "append", 1, 0, OPT_APPEND}, \ + { "dtb", 1, 0, OPT_DTB }, \ + { "initrd", 1, 0, OPT_INITRD }, \ + { "command-line", 1, 0, OPT_CMDLINE}, \ + { "reuse-cmdline", 0, NULL, OPT_REUSE_CMDLINE }, \ + + +#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" + +/* The following two #defines list ALL of the options added by all of the + * architecture's loaders. + * o main() uses this complete list to scan for its options, ignoring + * arch-specific/loader-specific ones. + * o Then, arch_process_options() uses this complete list to scan for its + * options, ignoring general/loader-specific ones. + * o Then, the file_type[n].load re-scans for options, using + * KEXEC_ARCH_OPTIONS plus its loader-specific options subset. + * Any unrecognised options cause an error here. + * + * This is done so that main()'s/arch_process_options()'s getopt_long() calls + * don't choose a kernel filename from random arguments to options they don't + * recognise -- as they now recognise (if not act upon) all possible options. + */ +#define KEXEC_ALL_OPTIONS KEXEC_ARCH_OPTIONS + +#define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR + +#endif /* KEXEC_ARCH_RISCV_OPTIONS_H */ diff --git a/kexec/arch/riscv/iomem.h b/kexec/arch/riscv/iomem.h new file mode 100644 index 000000000000..7671e26a9594 --- /dev/null +++ b/kexec/arch/riscv/iomem.h @@ -0,0 +1,10 @@ +#ifndef IOMEM_H +#define IOMEM_H + +#define SYSTEM_RAM "System RAM\n" +#define KERNEL_CODE "Kernel code\n" +#define KERNEL_DATA "Kernel data\n" +#define CRASH_KERNEL "Crash kernel\n" +#define IOMEM_RESERVED "Reserved\n" + +#endif diff --git a/kexec/arch/riscv/kexec-elf-riscv.c b/kexec/arch/riscv/kexec-elf-riscv.c new file mode 100644 index 000000000000..f3c011c4c1dc --- /dev/null +++ b/kexec/arch/riscv/kexec-elf-riscv.c @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +#include "kexec.h" +#include "dt-ops.h" /* For dtb_set/clear_initrd() */ +#include /* For ELF header handling */ +#include /* For EFBIG/EINVAL */ +#include /* For getpagesize() */ +#include "kexec-syscall.h" /* For KEXEC_ON_CRASH */ +#include "kexec-riscv.h" + + +/*********\ +* HELPERS * +\*********/ + +/* + * Go through the available physical memory regions and + * find one that can hold an image of the specified size. + * Note: This is called after get_memory_ranges so + * info->memory_range[] should be populated. Also note that + * memory ranges are sorted, so we'll return the first region + * that's big enough for holding the image. + */ +static int elf_riscv_find_pbase(struct kexec_info *info, off_t *addr, + off_t size) +{ + int i = 0; + off_t start = 0; + off_t end = 0; + int ret = 0; + + /* + * If this image is for a crash kernel, use the region + * the primary kernel has already reserved for us. + */ + if (info->kexec_flags & KEXEC_ON_CRASH) { + ret = get_crash_kernel_load_range((uint64_t *) &start, + (uint64_t *) &end); + if (!ret) { + /* + * Kernel should be aligned to the nearest + * hugepage (2MB for RV64, 4MB for RV32). + */ +#if __riscv_xlen == 64 + start = _ALIGN_UP(start, 0x200000); +#else + start = _ALIGN_UP(start, 0x400000); +#endif + if (end > start && ((end - start) >= size)) { + *addr = start; + return 0; + } + + return -EFBIG; + } else + return ENOCRASHKERNEL; + } + + for (i = 0; i < info->memory_ranges; i++) { + if (info->memory_range[i].type != RANGE_RAM) + continue; + + start = info->memory_range[i].start; + end = info->memory_range[i].end; + +#if __riscv_xlen == 64 + start = _ALIGN_UP(start, 0x200000); +#else + start = _ALIGN_UP(start, 0x400000); +#endif + + if (end > start && ((end - start) >= size)) { + *addr = start; + return 0; + } + } + + return -EFBIG; +} + +/**************\ +* ENTRY POINTS * +\**************/ + +int elf_riscv_probe(const char *buf, off_t len) +{ + struct mem_ehdr ehdr = {0}; + int ret = 0; + + ret = build_elf_exec_info(buf, len, &ehdr, 0); + if (ret < 0) + goto cleanup; + + if (ehdr.e_machine != EM_RISCV) { + fprintf(stderr, "Not for this architecture.\n"); + ret = -EINVAL; + goto cleanup; + } + + ret = 0; + + cleanup: + free_elf_info(&ehdr); + return ret; +} + +void elf_riscv_usage(void) +{ +} + +int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info) +{ + struct mem_ehdr ehdr = {0}; + struct mem_phdr *phdr = NULL; + off_t new_base_addr = 0; + off_t kernel_size = 0; + off_t page_size = getpagesize(); + off_t max_addr = 0; + off_t old_base_addr = 0; + off_t old_start_addr = 0; + int i = 0; + int ret = 0; + + if (info->file_mode) { + fprintf(stderr, "kexec_file not supported on this " + "architecture\n"); + return -EINVAL; + } + + /* Parse the ELF file */ + ret = build_elf_exec_info(buf, len, &ehdr, 0); + if (ret < 0) { + fprintf(stderr, "ELF exec parse failed\n"); + return -EINVAL; + } + + max_addr = elf_max_addr(&ehdr); + old_base_addr = max_addr; + old_start_addr = max_addr; + + /* + * Get the memory footprint, base physical + * and start address of the ELF image + */ + for (i = 0; i < ehdr.e_phnum; i++) { + phdr = &ehdr.e_phdr[i]; + if (phdr->p_type != PT_LOAD) + continue; + + /* + * Note: According to ELF spec the loadable regions + * are sorted on p_vaddr, not p_paddr. + */ + if (old_base_addr > phdr->p_paddr) + old_base_addr = phdr->p_paddr; + + if (phdr->p_vaddr == ehdr.e_entry || + phdr->p_paddr == ehdr.e_entry) + old_start_addr = phdr->p_paddr; + + kernel_size += _ALIGN_UP(phdr->p_memsz, page_size); + } + + if (old_base_addr == max_addr || kernel_size == 0) { + fprintf(stderr, "No loadable segments present on the " + "provided ELF image\n"); + return -EINVAL; + } + + if (old_start_addr == max_addr) { + fprintf(stderr, "Could not find the entry point address of " + "provided ELF image\n"); + return -EINVAL; + } + + dbgprintf("Got ELF with total memsz %luKB\n" + "Base paddr: 0x%lX, start_addr: 0x%lX\n", + kernel_size / 1024, old_base_addr, old_start_addr); + + /* Get a continuous physical region that can hold the kernel */ + ret = elf_riscv_find_pbase(info, &new_base_addr, kernel_size); + if (ret < 0) { + fprintf(stderr, "Could not find a memory region for the " + "provided ELF image\n"); + return ret; + } + + dbgprintf("New base paddr for the ELF: 0x%lX\n", new_base_addr); + + /* Re-set the base physical address of the ELF */ + for (i = 0; i < ehdr.e_phnum; i++) { + phdr = &ehdr.e_phdr[i]; + if (phdr->p_type != PT_LOAD) + continue; + + phdr->p_paddr -= old_base_addr; + phdr->p_paddr += new_base_addr; + } + + /* Re-set the entry point address */ + ehdr.e_entry = (old_start_addr - old_base_addr) + new_base_addr; + info->entry = (void *) ehdr.e_entry; + dbgprintf("New entry point for the ELF: 0x%llX\n", ehdr.e_entry); + + + /* Load the ELF executable */ + ret = elf_exec_load(&ehdr, info); + if (ret < 0) { + fprintf(stderr, "ELF exec load failed\n"); + return ret; + } + + ret = load_extra_segments(info, new_base_addr, + kernel_size, max_addr); + return ret; +} + + +/*******\ +* STUBS * +\*******/ + +int machine_verify_elf_rel(struct mem_ehdr *ehdr) +{ + if (ehdr->ei_data != ELFDATA2LSB) + return 0; +#if __riscv_xlen == 64 + if (ehdr->ei_class != ELFCLASS64) +#else + if (ehdr->ei_class != ELFCLASS32) +#endif + return 0; + if (ehdr->e_machine != EM_RISCV) + return 0; + return 1; +} + +void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), + struct mem_sym *UNUSED(sym), + unsigned long r_type, + void *UNUSED(location), + unsigned long UNUSED(address), + unsigned long UNUSED(value)) +{ + switch (r_type) { + default: + die("Unknown rela relocation: %lu\n", r_type); + break; + } +} diff --git a/kexec/arch/riscv/kexec-riscv.c b/kexec/arch/riscv/kexec-riscv.c new file mode 100644 index 000000000000..38d9a394aadd --- /dev/null +++ b/kexec/arch/riscv/kexec-riscv.c @@ -0,0 +1,431 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +#include "kexec-syscall.h" /* For KEXEC_ARCH_RISCV */ +#include "kexec.h" /* For OPT_MAX and concat_cmdline() */ +#include "mem_regions.h" /* For mem_regions_sort() */ +#include "dt-ops.h" /* For dtb_set_bootargs() */ +#include /* For KEXEC_ARCH_OPTIONS */ +#include /* For struct option */ +#include /* For stat() and struct stat */ +#include /* For free() */ +#include /* For EINVAL */ +#include /* For DeviceTree handling */ +#include "kexec-riscv.h" +#include "iomem.h" +#include + +const struct arch_map_entry arches[] = { + { "riscv32", KEXEC_ARCH_RISCV }, + { "riscv64", KEXEC_ARCH_RISCV }, + { NULL, 0 }, +}; + + +struct file_type file_type[] = { + {"elf-riscv", elf_riscv_probe, elf_riscv_load, elf_riscv_usage}, +}; +int file_types = sizeof(file_type) / sizeof(file_type[0]); + +static const char riscv_opts_usage[] = +" --append=STRING Append STRING to the kernel command line.\n" +" --dtb=FILE Use FILE as the device tree blob.\n" +" --initrd=FILE Use FILE as the kernel initial ramdisk.\n" +" --command-line=STRING Use STRING as the kernel's command line.\n" +" --reuse-cmdline Use kernel command line from running system.\n"; + +static struct riscv_opts arch_options = {0}; +static struct fdt_image provided_fdt = {0}; + +/****************\ +* COMMON HELPERS * +\****************/ + +int load_extra_segments(struct kexec_info *info, uint64_t kernel_base, + uint64_t kernel_size, uint64_t max_addr) +{ + struct fdt_image *fdt = arch_options.fdt; + char *initrd_buf = NULL; + off_t initrd_size = 0; + uint64_t initrd_base = 0; + uint64_t start = 0; + uint64_t end = 0; + uint64_t min_usable = kernel_base + kernel_size; + uint64_t max_usable = max_addr; + int ret = 0; + + /* Prepare the device tree */ + if (info->kexec_flags & KEXEC_ON_CRASH) { + ret = load_elfcorehdr(info); + if (ret) { + fprintf(stderr, "Couldn't create elfcorehdr\n"); + return ret; + } + + ret = dtb_add_range_property(&fdt->buf, &fdt->size, + elfcorehdr_mem.start, elfcorehdr_mem.end, + "chosen", "linux,elfcorehdr"); + if (ret) { + fprintf(stderr, "Couldn't add elfcorehdr to fdt\n"); + return ret; + } + + ret = get_crash_kernel_load_range(&start, &end); + if (ret) { + fprintf(stderr, "Couldn't get crashkenel region\n"); + return ret; + } + + ret = dtb_add_range_property(&fdt->buf, &fdt->size, start, end, + "chosen", "linux,usable-memory-range"); + if (ret) { + fprintf(stderr, "Couldn't add usable-memory-range to fdt\n"); + return ret; + } + + max_usable = end; + } else { + /* + * Make sure we remove elfcorehdr and usable-memory-range + * when switching from crash kernel to a normal one. + */ + dtb_delete_property(fdt->buf, "chosen", "linux,elfcorehdr"); + dtb_delete_property(fdt->buf, "chosen", "linux,usable-memory-range"); + } + + /* Do we need to include an initrd image ? */ + if (!arch_options.initrd_path && !arch_options.initrd_end) + dtb_clear_initrd(&fdt->buf, &fdt->size); + else if (arch_options.initrd_path) { + if (arch_options.initrd_end) + fprintf(stderr, "Warning: An initrd image was provided" + ", will ignore reuseinitrd\n"); + + initrd_buf = slurp_file(arch_options.initrd_path, + &initrd_size); + if (!initrd_buf) { + fprintf(stderr, "Couldn't read provided initrd\n"); + return -EINVAL; + } + + initrd_base = add_buffer_phys_virt(info, initrd_buf, + initrd_size, + initrd_size, 0, + min_usable, + max_usable, -1, 0); + + dtb_set_initrd(&fdt->buf, &fdt->size, initrd_base, + initrd_base + initrd_size); + + dbgprintf("Base addr for initrd image: 0x%lX\n", initrd_base); + max_usable = initrd_base; + } + + /* Add device tree */ + add_buffer_phys_virt(info, fdt->buf, fdt->size, fdt->size, 0, + min_usable, max_usable, -1, 0); + + return 0; +} + + +/**************\ +* ENTRY POINTS * +\**************/ + +void arch_usage(void) +{ + printf(riscv_opts_usage); +} + +int arch_process_options(int argc, char **argv) +{ + static const struct option options[] = { + KEXEC_ARCH_OPTIONS + { 0 }, + }; + static const char short_options[] = KEXEC_ARCH_OPT_STR; + struct stat st = {0}; + char *append = NULL; + char *cmdline = NULL; + void *tmp = NULL; + off_t tmp_size = 0; + int opt = 0; + int ret = 0; + + while ((opt = getopt_long(argc, argv, short_options, + options, 0)) != -1) { + switch (opt) { + case OPT_APPEND: + append = optarg; + break; + case OPT_CMDLINE: + if (cmdline) + fprintf(stderr, + "Warning: Kernel's cmdline " + "set twice !\n"); + cmdline = optarg; + break; + case OPT_REUSE_CMDLINE: + if (cmdline) + fprintf(stderr, + "Warning: Kernel's cmdline " + "set twice !\n"); + cmdline = get_command_line(); + break; + case OPT_DTB: + ret = stat(optarg, &st); + if (ret) { + fprintf(stderr, + "Could not find the provided dtb !\n"); + return -EINVAL; + } + arch_options.fdt_path = optarg; + break; + case OPT_INITRD: + ret = stat(optarg, &st); + if (ret) { + fprintf(stderr, + "Could not find the provided " + "initrd image !\n"); + return -EINVAL; + } + arch_options.initrd_path = optarg; + break; + default: + break; + } + } + + /* Handle Kernel's command line */ + if (append && !cmdline) + fprintf(stderr, "Warning: No cmdline provided, " + "using append string as cmdline\n"); + if (!append && !cmdline) + fprintf(stderr, "Warning: No cmdline or append string " + "provided\n"); + + if (append || cmdline) + /* + * Note that this also handles the case where "cmdline" + * or "append" is NULL. + */ + arch_options.cmdline = concat_cmdline(cmdline, append); + + /* Handle FDT image */ + if (!arch_options.fdt_path) { + ret = stat("/sys/firmware/fdt", &st); + if (ret) { + fprintf(stderr, "No dtb provided and " + "/sys/firmware/fdt is not present\n"); + return -EINVAL; + } + fprintf(stderr, "Warning: No dtb provided, " + "using /sys/firmware/fdt\n"); + arch_options.fdt_path = "/sys/firmware/fdt"; + } + + tmp = slurp_file(arch_options.fdt_path, &tmp_size); + if (!tmp) { + fprintf(stderr, "Couldn't read provided fdt\n"); + return -EINVAL; + } + + ret = fdt_check_header(tmp); + if (ret) { + fprintf(stderr, "Got an ivalid fdt image !\n"); + free(tmp); + return -EINVAL; + } + provided_fdt.buf = tmp; + provided_fdt.size = tmp_size; + + if (arch_options.cmdline) { + ret = dtb_set_bootargs(&provided_fdt.buf, &provided_fdt.size, + arch_options.cmdline); + if (ret < 0) { + fprintf(stderr, "Could not set bootargs on " + "the fdt image\n"); + return ret; + } + } + + arch_options.fdt = &provided_fdt; + + return 0; +} + +/* + * This one is called after arch_process_options so we already + * have an fdt image in place. + */ +void arch_reuse_initrd(void) +{ + const uint32_t *prop32 = NULL; + uint32_t addr_cells = 0; + const void *prop = 0; + int prop_size = 0; + uint64_t initrd_start = 0; + uint64_t initrd_end = 0; + int chosen_offset = 0; + struct fdt_image *fdt = &provided_fdt; + + chosen_offset = fdt_subnode_offset(fdt->buf, 0, "chosen"); + if (chosen_offset < 0) { + fprintf(stderr, "No /chosen node found on fdt image " + "unable to reuse initrd\n"); + return; + } + + prop32 = fdt_getprop(fdt->buf, 0, "#address-cells", NULL); + if (!prop32) { + fprintf(stderr, "No #address-cells property on root node\n"); + return; + } + addr_cells = be32_to_cpu(*prop32); + + prop = fdt_getprop(fdt->buf, chosen_offset, + "linux,initrd-start", &prop_size); + if (!prop) { + fprintf(stderr, "Could not get linux,initrd-start\n"); + return; + } + dtb_extract_int_property(&initrd_start, prop, addr_cells); + + prop = fdt_getprop(fdt->buf, chosen_offset, + "linux,initrd-end", &prop_size); + if (!prop) { + fprintf(stderr, "Could not get linux,initrd-end\n"); + return; + } + dtb_extract_int_property(&initrd_end, prop, addr_cells); + + arch_options.initrd_start = initrd_start; + arch_options.initrd_end = initrd_end; + dbgprintf("initrd_start: 0x%lX, initrd_end: 0x%lX\n", + initrd_start, initrd_end); + +} + +static bool to_be_excluded(char *str, unsigned long long start, unsigned long long end) +{ + if (!strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) { + uint64_t load_start, load_end; + + if (!get_crash_kernel_load_range(&load_start, &load_end) && + (load_start == start) && (load_end == end)) + return false; + + return true; + } + + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA))) + return false; + else + return true; +} + +int get_memory_ranges(struct memory_range **range, int *num_ranges, + unsigned long kexec_flags) +{ + struct memory_ranges sysmem_ranges = {0}; + const char *iomem = proc_iomem(); + struct memory_range excl_range; + unsigned long long start, end; + int consumed, count, ret = 0; + FILE *fp = NULL, *sp = NULL; + char line[MAX_LINE], *str; + + fp = fopen(iomem, "r"); + if (!fp) { + fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); + return -1; + } + + sp = fopen(iomem, "r"); + if (!sp) { + fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); + ret = -1; + goto err; + } + + /* + * Perform two passes: First add all System RAM, and then + * exclude the "Reserved" ranges" + */ + while (fgets(line, sizeof(line), fp) != 0) { + count = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); + if (count != 2) + continue; + str = line + consumed; + + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) { + ret = mem_regions_alloc_and_add(&sysmem_ranges, + start, end - start + 1, RANGE_RAM); + if (ret) { + fprintf(stderr, + "Cannot allocate memory for ranges\n"); + ret = -ENOMEM; + goto err; + } + + } + } + + while (fgets(line, sizeof(line), sp) != 0) { + count = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); + if (count != 2) + continue; + str = line + consumed; + + if (to_be_excluded(str, start, end)) { + excl_range.start = start; + excl_range.end = end; + + ret = mem_regions_alloc_and_exclude(&sysmem_ranges, &excl_range); + if (ret) { + fprintf(stderr, + "Cannot allocate memory for ranges (exclude)\n"); + ret = -ENOMEM; + goto err; + } + } + } + + *range = sysmem_ranges.ranges; + *num_ranges = sysmem_ranges.size; + + dbgprint_mem_range("System RAM ranges;", + sysmem_ranges.ranges, sysmem_ranges.size); + + ret = 0; + err: + if (fp) + fclose(fp); + if (sp) + fclose(sp); + return ret; +} + +/*******\ +* STUBS * +\*******/ + +int arch_compat_trampoline(struct kexec_info *UNUSED(info)) +{ + return 0; +} + +void arch_update_purgatory(struct kexec_info *UNUSED(info)) +{ +} + +int arch_do_exclude_segment(struct kexec_info *UNUSED(info), struct kexec_segment *UNUSED(segment)) +{ + return 0; +} diff --git a/kexec/arch/riscv/kexec-riscv.h b/kexec/arch/riscv/kexec-riscv.h new file mode 100644 index 000000000000..c4323a65dacf --- /dev/null +++ b/kexec/arch/riscv/kexec-riscv.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 FORTH-ICS/CARV + * Nick Kossifidis + */ + +struct fdt_image { + char *buf; + off_t size; +}; + +struct riscv_opts { + char *cmdline; + char *fdt_path; + char *initrd_path; + uint64_t initrd_start; + uint64_t initrd_end; + struct fdt_image *fdt; +}; + +/* crashdump-riscv.c */ +extern struct memory_range elfcorehdr_mem; +int load_elfcorehdr(struct kexec_info *info); + +/* kexec-riscv.c */ +int load_extra_segments(struct kexec_info *info, uint64_t kernel_base, + uint64_t kernel_size, uint64_t max_addr); + +int elf_riscv_probe(const char *buf, off_t len); +void elf_riscv_usage(void); +int elf_riscv_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c index 0a96b75f65aa..3e285ab2043b 100644 --- a/kexec/dt-ops.c +++ b/kexec/dt-ops.c @@ -4,9 +4,11 @@ #include #include #include +#include #include "kexec.h" #include "dt-ops.h" +#include "mem_regions.h" static const char n_chosen[] = "chosen"; @@ -95,7 +97,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, strcpy(new_node, "/"); strcat(new_node, node); - + nodeoffset = fdt_path_offset(new_dtb, new_node); if (nodeoffset == -FDT_ERR_NOTFOUND) { @@ -174,3 +176,441 @@ int dtb_delete_property(char *dtb, const char *node, const char *prop) free(new_node); return result; } + +static int dtb_get_num_cells(char *dtb, int nodeoffset, uint32_t *addr_cells, + uint32_t *size_cells, bool recursive) +{ + const uint32_t *prop32 = NULL; + int curr_offset = nodeoffset; + int prop_len = 0; + *addr_cells = 0; + *size_cells = 0; + + do { + prop32 = fdt_getprop(dtb, curr_offset, "#address-cells", &prop_len); + curr_offset = fdt_parent_offset(dtb, curr_offset); + } while (!prop32 && prop_len == -FDT_ERR_NOTFOUND && recursive); + + if (!prop32) { + dbgprintf("Could not get #address-cells property for %s (%s)\n", + fdt_get_name(dtb, nodeoffset, NULL), fdt_strerror(nodeoffset)); + return -EINVAL; + } + *addr_cells = fdt32_to_cpu(*prop32); + + curr_offset = nodeoffset; + do { + prop32 = fdt_getprop(dtb, curr_offset, "#size-cells", &prop_len); + curr_offset = fdt_parent_offset(dtb, curr_offset); + } while (!prop32 && prop_len == -FDT_ERR_NOTFOUND && recursive); + + if (!prop32) { + dbgprintf("Could not get #size-cells property for %s (%s)\n", + fdt_get_name(dtb, nodeoffset, NULL), fdt_strerror(nodeoffset)); + return -EINVAL; + } + *size_cells = fdt32_to_cpu(*prop32); + + dbgprintf("%s: #address-cells:%d #size-cells:%d\n", + fdt_get_name(dtb, nodeoffset, NULL), *addr_cells, *size_cells); + + return 0; +} + +void dtb_extract_int_property(uint64_t *val, const void *buf, uint32_t cells) +{ + const uint32_t *prop32 = NULL; + const uint64_t *prop64 = NULL; + + if (cells == 1) { + prop32 = (const uint32_t *) buf; + *val = (uint64_t) be32_to_cpu(*prop32); + } else { + /* Skip any leading cells */ + prop64 = (const uint64_t *) (uint32_t *)buf + cells - 2; + *val = (uint64_t) be64_to_cpu(*prop64); + } +} + +void dtb_fill_int_property(void *buf, uint64_t val, uint32_t cells) +{ + uint32_t prop32 = 0; + uint64_t prop64 = 0; + + if (cells == 1) { + prop32 = cpu_to_fdt32((uint32_t) val); + memcpy(buf, &prop32, sizeof(uint32_t)); + } else { + prop64 = cpu_to_fdt64(val); + /* Skip any leading cells */ + memcpy((uint64_t *)(uint32_t *)buf + cells - 2, + &prop64, sizeof(uint64_t)); + } +} + +int dtb_add_range_property(char **dtb, off_t *dtb_size, uint64_t start, uint64_t end, + const char *parent, const char *name) +{ + uint32_t addr_cells = 0; + uint32_t size_cells = 0; + char *nodepath = NULL; + void *prop = NULL; + int nodeoffset = 0; + int prop_size = 0; + int ret = 0; + + nodepath = malloc(strlen("/") + strlen(parent) + 1); + if (!nodepath) { + dbgprintf("%s: malloc failed\n", __func__); + return -ENOMEM; + } + + strcpy(nodepath, "/"); + strcat(nodepath, parent); + + nodeoffset = fdt_path_offset(*dtb, nodepath); + if (nodeoffset < 0) { + dbgprintf("%s: fdt_path_offset(%s) failed: %s\n", __func__, + nodepath, fdt_strerror(nodeoffset)); + free(nodepath); + return nodeoffset; + } + free(nodepath); + + ret = dtb_get_num_cells(*dtb, nodeoffset, &addr_cells, &size_cells, true); + if (ret < 0) + return ret; + + /* Can the range fit with the given address/size cells ? */ + if ((addr_cells == 1) && (start >= (1ULL << 32))) + return -EINVAL; + + if ((size_cells == 1) && ((end - start + 1) >= (1ULL << 32))) + return -EINVAL; + + prop_size = sizeof(uint32_t) * (addr_cells + size_cells); + prop = malloc(prop_size); + + dtb_fill_int_property(prop, start, addr_cells); + dtb_fill_int_property((void *)((uint32_t *)prop + addr_cells), + end - start + 1, size_cells); + + /* Add by node path name */ + return dtb_set_property(dtb, dtb_size, parent, name, prop, prop_size); +} + +/************************\ +* MEMORY RANGES HANDLING * +\************************/ + +static int dtb_add_memory_range(struct memory_ranges *mem_ranges, uint64_t start, + uint64_t end, unsigned type) +{ + struct memory_range this_region = {0}; + struct memory_range *ranges = mem_ranges->ranges; + int i = 0; + int ret = 0; + + if (start == end) { + dbgprintf("Ignoring empty region\n"); + return -EINVAL; + } + + /* Check if we are adding an existing region */ + for (i = 0; i < mem_ranges->size; i++) { + if (start == ranges[i].start && end == ranges[i].end) { + dbgprintf("Duplicate: 0x%lx - 0x%lx\n", start, end); + + if (type == ranges[i].type) + return 0; + else if (type == RANGE_RESERVED) { + ranges[i].type = RANGE_RESERVED; + return 0; + } + + dbgprintf("Conflicting types for region: 0x%lx - 0x%lx\n", + start, end); + return -EINVAL; + } + } + + /* + * Reserved regions may be part of an existing /memory + * region and shouldn't overlap according to spec, so + * since we add /memory regions first, we can exclude + * reserved regions here from the existing /memory regions + * included in ranges[], so that we don't have the same + * region twice. + */ + if (type == RANGE_RESERVED) { + this_region.start = start; + this_region.end = end - 1; + this_region.type = type; + ret = mem_regions_exclude(mem_ranges, &this_region); + if (ret) + return ret; + } + + ret = mem_regions_alloc_and_add(mem_ranges, start, + end - start, type); + + return ret; +} + +static int dtb_add_memory_region(char *dtb, int nodeoffset, + struct memory_ranges *mem_ranges, int type) +{ + uint32_t root_addr_cells = 0; + uint32_t root_size_cells = 0; + uint64_t addr = 0; + uint64_t size = 0; + const char *reg = NULL; + int prop_size = 0; + int offset = 0; + int entry_size = 0; + int num_entries = 0; + int ret = 0; + + /* + * Get address-cells and size-cells properties (according to + * binding spec these are the same as in the root node) + */ + ret = dtb_get_num_cells(dtb, 0, &root_addr_cells, &root_size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells on root node !\n"); + return ret; + } + + /* + * Parse the reg array, acording to device tree spec it includes + * an arbitary number of
pairs + */ + entry_size = (root_addr_cells + root_size_cells) * sizeof(uint32_t); + reg = fdt_getprop(dtb, nodeoffset, "reg", &prop_size); + if (!reg) { + dbgprintf("Warning: Malformed memory region with no reg property (%s) !\n", + fdt_get_name(dtb, nodeoffset, NULL)); + return -EINVAL; + } + + num_entries = prop_size / entry_size; + dbgprintf("Got region with %i entries: %s\n", num_entries, + fdt_get_name(dtb, nodeoffset, NULL)); + + for (num_entries--; num_entries >= 0; num_entries--) { + offset = num_entries * entry_size; + + dtb_extract_int_property(&addr, reg + offset, + root_addr_cells); + offset += root_addr_cells * sizeof(uint32_t); + + dtb_extract_int_property(&size, reg + offset, + root_size_cells); + + ret = dtb_add_memory_range(mem_ranges, addr, + addr + size, type); + if (ret) + return ret; + } + + return 0; +} + +static int dtb_parse_memory_reservations_table(char *dtb, struct memory_ranges *mem_ranges) +{ + int total_memrsrv = 0; + uint64_t addr = 0; + uint64_t size = 0; + int ret = 0; + int i = 0; + + total_memrsrv = fdt_num_mem_rsv(dtb); + for (i = 0; i < total_memrsrv; i++) { + ret = fdt_get_mem_rsv(dtb, i, &addr, &size); + if (ret) + continue; + ret = dtb_add_memory_range(mem_ranges, addr, addr + size - 1, + RANGE_RESERVED); + if (ret) + return ret; + } + + return 0; +} + +static int dtb_get_reserved_memory_node(char *dtb) +{ + uint32_t root_addr_cells = 0; + uint32_t root_size_cells = 0; + uint32_t addr_cells = 0; + uint32_t size_cells = 0; + int prop_size = 0; + int nodeoffset = 0; + int ret = 0; + + /* Get address / size cells from root node */ + ret = dtb_get_num_cells(dtb, 0, &root_addr_cells, &root_size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells on root node !\n"); + return ret; + } + + /* This calls fdt_next_node internaly */ + nodeoffset = fdt_subnode_offset(dtb, 0, "reserved-memory"); + if (nodeoffset == -FDT_ERR_NOTFOUND) { + return nodeoffset; + } else if (nodeoffset < 0) { + dbgprintf("Error while looking for reserved-memory: %s\n", + fdt_strerror(nodeoffset)); + return nodeoffset; + } + + /* Look for the ranges property */ + fdt_getprop(dtb, nodeoffset, "ranges", &prop_size); + if (prop_size < 0) { + fprintf(stderr, "Malformed reserved-memory node (no ranges property) !\n"); + return -EINVAL; + } + + /* Verify address-cells / size-cells */ + ret = dtb_get_num_cells(dtb, nodeoffset, &addr_cells, &size_cells, false); + if (ret < 0) { + dbgprintf("No address/size cells property on reserved-memory node\n"); + return ret; + } + + if (addr_cells != root_addr_cells) { + fprintf(stderr, "Invalid #address-cells property on reserved-memory node\n"); + return -EINVAL; + } + + if (size_cells != root_size_cells) { + fprintf(stderr, "Invalid #size-cells property on reserved-memory node\n"); + return -EINVAL; + + } + + return nodeoffset; +} + +static int dtb_parse_reserved_memory_node(char *dtb, struct memory_ranges *mem_ranges) +{ + int nodeoffset = 0; + int node_depth = 0; + int parent_depth = 0; + int ret = 0; + + nodeoffset = dtb_get_reserved_memory_node(dtb); + if (nodeoffset == -FDT_ERR_NOTFOUND) + return 0; + else if (nodeoffset < 0) + return nodeoffset; + + /* Got the parent node, check for sub-nodes */ + + /* fdt_next_node() increases or decreases depth */ + node_depth = parent_depth; + nodeoffset = fdt_next_node(dtb, nodeoffset, &node_depth); + if (ret < 0) { + dbgprintf("Unable to get next node: %s\n", + fdt_strerror(ret)); + return -EINVAL; + } + + while (node_depth != parent_depth) { + + ret = dtb_add_memory_region(dtb, nodeoffset, + mem_ranges, RANGE_RESERVED); + if (ret) + return ret; + + nodeoffset = fdt_next_node(dtb, nodeoffset, &node_depth); + if (ret < 0) { + dbgprintf("Unable to get next node: %s\n", + fdt_strerror(ret)); + return -EINVAL; + } + } + + return 0; +} + +static int dtb_parse_memory_nodes(char *dtb, struct memory_ranges *mem_ranges) +{ + int nodeoffset = 0; + int num_regions = 0; + const char* dev_type = 0; + int prop_size = 0; + int ret = 0; + + for (; ; num_regions++) { + nodeoffset = fdt_subnode_offset(dtb, nodeoffset, + "memory"); + if (nodeoffset < 0) + break; + + dbgprintf("Got memory node at depth: %i\n", fdt_node_depth(dtb, nodeoffset)); + + /* Look for the device_type property */ + dev_type = fdt_getprop(dtb, nodeoffset, "device_type", &prop_size); + if (prop_size < 0) { + fprintf(stderr, "Malformed /memory node (no device-type property) !\n"); + return -EINVAL; + } + + if (strncmp(dev_type, "memory", prop_size)) { + dbgprintf("Got unknown dev_type property: %s\n", dev_type); + continue; + } + + ret = dtb_add_memory_region(dtb, nodeoffset, mem_ranges, RANGE_RAM); + if (ret) + return ret; + } + + if (!num_regions) { + dbgprintf("Malformed dtb, no /memory nodes present !\n"); + return -EINVAL; + } + + dbgprintf("Got %i /memory nodes\n", num_regions); + + return 0; +} + +int dtb_get_memory_ranges(char *dtb, struct memory_ranges *mem_ranges, struct memory_ranges *extra_ranges) +{ + int i = 0; + int ret = 0; + + /* Fill mem_ranges[] by parsing the device tree */ + ret = dtb_parse_memory_nodes(dtb, mem_ranges); + if (ret) + return ret; + + ret = dtb_parse_memory_reservations_table(dtb, mem_ranges); + if (ret) + return ret; + + ret = dtb_parse_reserved_memory_node(dtb, mem_ranges); + if (ret) + return ret; + + /* Append any extra ranges provided by the caller (e.g. initrd) */ + for (i = 0; extra_ranges != NULL && i < extra_ranges->size; i++) { + dbgprintf("Adding extra range: 0x%llx - 0x%llx (%s)\n", + extra_ranges->ranges[i].start, + extra_ranges->ranges[i].end, + extra_ranges->ranges[i].type == RANGE_RESERVED ? + "RANGE_RESERVED" : "RANGE_RAM"); + + ret = dtb_add_memory_range(mem_ranges, extra_ranges->ranges[i].start, + extra_ranges->ranges[i].end, extra_ranges->ranges[i].type); + if (ret) + return ret; + } + + mem_regions_sort(mem_ranges); + + return 0; +} diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h index 03659ce283db..3014205d8e98 100644 --- a/kexec/dt-ops.h +++ b/kexec/dt-ops.h @@ -11,4 +11,11 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, int dtb_delete_property(char *dtb, const char *node, const char *prop); +void dtb_extract_int_property(uint64_t *val, const void *buf, uint32_t cells); +void dtb_fill_int_property(void *buf, uint64_t val, uint32_t cells); +int dtb_add_range_property(char **dtb, off_t *dtb_size, uint64_t start, uint64_t end, + const char *node, const char* parent); +int dtb_get_memory_ranges(char *dtb, struct memory_ranges *mem_ranges, + struct memory_ranges *extra_ranges); + #endif diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h index cc32c0162aec..89591ad17e7d 100644 --- a/kexec/kexec-syscall.h +++ b/kexec/kexec-syscall.h @@ -140,6 +140,7 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, #define KEXEC_ARCH_MIPS_LE (10 << 16) #define KEXEC_ARCH_MIPS ( 8 << 16) #define KEXEC_ARCH_CRIS (76 << 16) +#define KEXEC_ARCH_RISCV (243 << 16) #define KEXEC_ARCH_LOONGARCH (258 << 16) #define KEXEC_MAX_SEGMENTS 16 @@ -187,5 +188,8 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd, #if defined(__loongarch__) #define KEXEC_ARCH_NATIVE KEXEC_ARCH_LOONGARCH #endif +#if defined(__riscv__) || defined(__riscv) +#define KEXEC_ARCH_NATIVE KEXEC_ARCH_RISCV +#endif #endif /* KEXEC_SYSCALL_H */ diff --git a/purgatory/Makefile b/purgatory/Makefile index 4d2d07134bd5..7d1175f2445c 100644 --- a/purgatory/Makefile +++ b/purgatory/Makefile @@ -25,6 +25,7 @@ include $(srcdir)/purgatory/arch/ia64/Makefile include $(srcdir)/purgatory/arch/mips/Makefile include $(srcdir)/purgatory/arch/ppc/Makefile include $(srcdir)/purgatory/arch/ppc64/Makefile +include $(srcdir)/purgatory/arch/riscv/Makefile include $(srcdir)/purgatory/arch/s390/Makefile include $(srcdir)/purgatory/arch/sh/Makefile include $(srcdir)/purgatory/arch/x86_64/Makefile diff --git a/purgatory/arch/riscv/Makefile b/purgatory/arch/riscv/Makefile new file mode 100644 index 000000000000..49a6fef4a904 --- /dev/null +++ b/purgatory/arch/riscv/Makefile @@ -0,0 +1,7 @@ +# +# Purgatory riscv +# + +riscv_PURGATORY_SRCS = + +dist += purgatory/arch/riscv/Makefile $(riscv_PURGATORY_SRCS) -- 2.48.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5A02CC369D9 for ; Tue, 22 Apr 2025 19:47:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=H+s6mhlCVnL+OM1yL00Uyf4QJppjCwh/jnIWziF7e08=; b=vSeFk5xRZaRflr hGRjOyCMnEi4Me1FliG1KwrTiTMuUQYEJdHnopQ3gP36Ia9wsUO8fLStTd7fPlaT9s0gCb5lNYPIP htXRshpXYRhPUWX9e+Cibx9rXzsWQk2fk+q7PFYVh798OfudhUOBLHtE+9L0UcRv351Il6/pNNLlh qu3fOLD7B7pdOIzxjxFiJsrRFYEjdWSon4ZUK+3uzg5VuDzSRTFPTt6JpbY7VFhDhKD50HnFzG7p+ PPexA63rDDS6WVI1geBLh8j/DaoHp9qL6xj6keHTCe4YsS90/Hd7z3ExhSu9DxmFH3wb9zhXZWSIf r06m34/yjhUzeazuyPPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1u7JaT-00000008LZ1-2KH4; Tue, 22 Apr 2025 19:47:21 +0000 Received: from sea.source.kernel.org ([2600:3c0a:e001:78e:0:1991:8:25]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1u7GOw-00000007tHA-1Qup; Tue, 22 Apr 2025 16:23:16 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 8806D43C8D; Tue, 22 Apr 2025 16:23:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44630C4CEE9; Tue, 22 Apr 2025 16:23:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1745338993; bh=5SXVdgY6N49lH5/liRgjfb+Iad1OUbcV8YvCE7OJPxo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aWHx8aicB9liJT7yMTV96S9x9MRWP+DJAstSe+KRAODUCgEiLT7KNnH36FAkHDyBr Afqxm+kaTcZ+sN0Q4FEb30CFZ4A0E5ZL/rtSkVO4254LgJvklMkX9QYA6Djz3fF3z8 oU2abAu40pVZj1vGctPuqjTQvj+SlUya03S5wr5T1SY0qeHC+YBk02znxx0Tm7hHPa g5MRfL0XUGtuI71jTBQ5dsLnVOx0kElTijmESnWw/vQzFoWk98YLOJUrzcwP2qRZvg J6LxH/IKNmkcnq+2csnoN4tD5FGTCIRfrVf/akE1+m0JDL+yEOa4DloW/y9y2vmUZ+ xPJTmBWQkWkag== From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= To: Simon Horman , Simon Horman , Nick Kossifidis , Song Shuai , Li Zhengyu , kexec@lists.infradead.org Cc: Dave Young , Yixun Lan , Xianting Tian , linux-riscv@lists.infradead.org, =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Subject: [PATCH v2 1/4] RISC-V: Add support for riscv kexec/kdump on kexec-tools Date: Tue, 22 Apr 2025 18:22:57 +0200 Message-ID: <20250422162304.169431-2-bjorn@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250422162304.169431-1-bjorn@kernel.org> References: <20250422162304.169431-1-bjorn@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250422_092314_490498_C77D21DC X-CRM114-Status: GOOD ( 37.90 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RnJvbTogTmljayBLb3NzaWZpZGlzIDxtaWNrQGljcy5mb3J0aC5ncj4KClRoaXMgcGF0Y2ggYWRk cyBzdXBwb3J0IGZvciBsb2FkaW5nIHRoZSBFTEYga2VybmVsIGltYWdlLiBJdCBwYXJzZXMKdGhl IGN1cnJlbnQvcHJvdmlkZWQgZGV2aWNlIHRyZWUgdG8gZGV0ZXJtaW5lIHRoZSBzeXN0ZW0ncyBt ZW1vcnkKbGF5b3V0LCBhbmQgL3Byb2MvaW9tZW0gZm9yIHRoZSB2YXJpb3VzIGtlcm5lbCBzZWdt ZW50cy4KClRlc3RlZCBvbiBRZW11J3MgcnY2NCB2aXJ0IG1hY2hpbmUgYW5kIFNvQyBvZiBULUhl YWQgUklTQy1WIFh1YW50aWUKOTEwIENQVS4KCk5vdywgc29tZSBoaXN0b3J5OiBUaGUgZmlyc3Qg c3RhYiBhdCBzdXBwb3J0aW5nIGtleGVjLXRvb2xzIG9uIFJJU0MtVgp3YXMgZG9uZSBieSBOaWNr IEtvc3NpZmlkaXMuIFRoZSBpbml0aWFsIHBhdGNoIGhhcyBzaW5jZSB0aGVuIGhhZCBhCm51bWJl ciBvZiBpbXByb3ZlbWVudHMvZml4ZXMgYnkgb3RoZXIgYXV0aG9ycy4gR2l2ZW4sIHRoaXMgaXMg dGhlCmZpcnN0IGNvbW1pdCBmb3IgUklTQy1WLCBjYXJyeWluZyB0aGUgZml4ZXMvY2hhbmdlcyBj b21taXRzIGluIHRoZQp1cHN0cmVhbSB0cmVlIGRvZXMgbm90IHJlYWxseSBhZGQgYW55dGhpbmcg KGJpc2VjdGFiaWxpdHkpLgoKSW5zdGVhZCBhbGwgdGhlIGZpeGVzIHRoYXQgd2VyZSBhcHBsaWVk IHRvIE5pY2sncyBmaXJzdCBjb21taXQgaXMKb3V0bGluZWQgYmVsb3c6CgpZaXh1biBMYW4sIGFu ZCBYaWFudGluZyBUaWFuOgogICogRml4ZWQgYSBmYWlsdXJlIHRvIGZhaWwgdG8gZmluZCBmcmVl IG1lbW9yeSBhcmVhIGZvciBkdGIgbG9hZCB3aGVuCiAgICB1c2luZyBpbml0cmQgaW1hZ2UgWzFd LgogICogRml4ZWQgbWVtb3J5IHJhbmdlIHNpemUgY2FsY3VsYXRpb24gaW4KICAgIGtleGVjL2Fy Y2gvcmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmM6ODUKClNpbW9uIEhvcm1hbjoKICAqIHdvcmtmbG93 OiBBZGQgcmlzY3Y2NAoKICAgIEFkZCByaXNjdjY0IHRvIG1hdHJpeCBvZiBidWlsZCBhcmNoaXRl Y3R1cmVzLgogICogUklTQy1WOiBkaXN0cmlidXRlIHB1cmdhdG9yeS9yaXNjdi9NYWtlZmlsZQoK ICAgIEluY2x1ZGUgcHVyZ2F0b3J5L3Jpc2N2L01ha2VmaWxlIGluIGRpc3RyaWJ1dGlvbiB0YXJi YWxsLgoKICAgIExvY2FsIHBhdGNoIGFzIGl0IGlzIHBsYW5uZWQgdG8gc3VnZ2VzdCB0aGlzIGFz IGEgZml4IGZvciB0aGUKICAgIHBhdGNoIHRoYXQgaW50cm9kdWNlZCB0aGlzIHByb2JsZW0uIFsy XQoKU29uZyBTaHVhaToKICAqIFJJU0MtVjogRml4IHRoZSB1bmRlY2xhcmVkIOKAmEVNX1JJU0NW 4oCZIGJ1aWxkIGZhaWx1cmUKCiAgICBVc2UgbG9jYWwgYGVsZi5oYCBpbnN0ZWFkIG9mIGBsaW51 eC9lbGYuaGAgdG8gZml4IHRoaXMgYnVpbGQKICAgIGVycm9yOgoKICAgIGBgYAogICAga2V4ZWMv YXJjaC9yaXNjdi9jcmFzaGR1bXAtcmlzY3YuYzoxNzoxMzogZXJyb3I6IOKAmEVNX1JJU0NW4oCZ IHVuZGVjbGFyZWQgaGVyZSAobm90IGluIGEgZnVuY3Rpb24pOyBkaWQgeW91IG1lYW4g4oCYRU1f Q1JJU+KAmT8KICAgICAgLm1hY2hpbmUgPSBFTV9SSVNDViwKICAgICAgICAgICAgICAgICBefn5+ fn5+fgogICAgICAgICAgICAgICAgIEVNX0NSSVMKICAgIGBgYAoKICAqIFJJU0MtVjogQ29ycmVj dCB0aGUgdXNhZ2Ugb2YgY29tbWFuZCBsaW5lIG9wdGlvbgoKICAgIFJJU0MtViBwcm9jZXNzIE9Q VF9DTURMSU5FIHdpdGggdGhlICJjb21tYW5kLWxpbmUiIHBhcnR0ZW4sIGJ1dAogICAgdGhlIHJp c2N2X29wdHNfdXNhZ2Ugc2hvd3MgdGhlICJjbWRsaW5lIiBvcHRpb24uIFNvIGNvcnJlY3QgdGhl CiAgICB1c2FnZSdzIG91dHB1dC4KCiAgKiBSSVNDLVY6IFVzZSBsaW51eCx1c2FibGUtbWVtb3J5 LXJhbmdlIGZvciBjcmFzaCBrZXJuZWwKCiAgICBOb3cgd2UgdXNlICJtZW1lb3J5OjpsaW51eCx1 c2FibGUtbWVtb3J5IiB0byBpbmRpY2F0ZSB0aGUKICAgIGF2YWlsYWJsZSBtZW1vcnkgZm9yIHRo ZSBjcmFzaCBrZXJuZWwuCgogICAgV2hpbGUgYm9vdGluZyB3aXRoIFVFRkksIHRoZSBjcmFzaCBr ZXJuZWwgd291bGQgdXNlIGVmaS5tZW1tYXAgdG8KICAgIHJlLXBvcHVsYXRlIG1lbWJsb2NrIGFu ZCB0aGVuIGZpcnN0IGtlcm5lbCdzIG1lbW9yeSB3b3VsZCBiZQogICAgY29ycnB1dGVkLiBDb25z ZXF1ZW50bHksIHRoZSAvcHJvYy92bWNvcmUgZmlsZSBmYWlsZWQgdG8gY3JlYXRlIGluCiAgICBt eSBsb2NhbCB0ZXN0LgoKICAgIEFuZCBhY2NvcmRpbmcgdG8gImNob3NlbiIgZHRzY2hlbWEgWzNd LCB0aGUgYXZhaWxhYmxlIG1lbW9yeSBmb3IKICAgIHRoZSBjcmFzaCBrZXJuZWwgc2hvdWxkIGJl IGhlbGQgdmlhCiAgICAiY2hvc2VuOjpsaW51eCx1c2FibGUtbWVtb3J5LXJhbmdlIiBwcm9wZXJ0 eSB3aGljaCB3aWxsIHJlLWNhcAogICAgbWVtYmxvY2sgZXZlbiBhZnRlciBVRUZJJ3MgcmUtcG9w dWxhdGlvbi4KCiAgKiBSSVNDLVY6IEdldCBtZW1vcnkgcmFuZ2VzIGZyb20gaW9tZW0KCiAgICBX aGVuIGJvb3Rpbmcgd2l0aCBVRUZJLCBMaW51eCBtYXJrcyB0aGUgUnVudGltZSBDb2RlL0RhdGEg bWVtb3J5CiAgICBhcyBuby1tYXAgYW5kIHRoZW4gZXhwb3J0cyBpdCB0byAiUmVzZXJ2ZWQiIGlv bWVtX3Jlc291cmNlLgoKICAgIEtleGMtdG9vbHMgdXNlcyBkdGJfZ2V0X21lbW9yeV9yYW5nZXMo KSBmdW5jdGlvbiB0byBnZXQgbWVtb3J5CiAgICByYW5nZXMgdmlhIHBhcnNpbmcgZHRiLCBidXQg aXQgY2FuJ3Qgc2VlIHRoZSBSZXNlcnZlZCBFRkkgUnVudGltZQogICAgbWVtb3J5LiBUaGF0IHdv dWxkIGNvcnJ1cHQgRUZJIFJ1bnRpbWUgbWVtb3J5IGFuZCBmYWlsIHRoZSBrZXhlY2VkCiAgICBr ZXJuZWwgdG8gZGVhbCBFRkkgc3R1ZmYuCgogICAgSW4gbXkgdGVzdCwgdGhlIGtleGVjZWQga2Vy bmVsIHdhcm5lZCAiZWZpOiBTeXN0ZW0gdGFibGUgc2lnbmF0dXJlCiAgICBpbmNvcnJlY3QhIiBh bmQgdGhlbiBwYW5pY2VkIGF0IGVmaV9jYWxsX3J0cygpIGR1ZSB0byB0aGUgbnVsbAogICAgZWZp LnJ1bnRpbWUuCgogICAgU28gd2Ugc2hvdWxkIHVzZSAvcHJvYy9pb21lbSB0byBnZXQgbWVtb3J5 IHJhbmdlcy4KCkJqw7ZybiBUw7ZwZWw6CiAgKiBNYXNzYWdlZCB0aGlzIGNvbW1pdCBtZXNzYWdl IQogICogRml4ZWQgdXAgdGhlIGJ1aWxkLCBieSBhZGRpbmcgbWlzc2luZyBSViBzdHViLgogICog UklTQy1WOiBPbmx5IGNhcCB0aGUgdXBwZXIvZW5kIHVzYWJsZSBtZW1vcnkgd2luZG93CgogICAg V2hlbiBsb2FkaW5nIHRoZSBpbml0cmQgaW4gdGhlIGtleGVjX2xvYWQgZmxvdywgbWVtb3J5IGZv ciB0aGUKICAgIHNlZ21lbnRzIGFyZSBzZWFyY2hlZCBmcm9tIGVuZCB0byBzdGFydC4gT25seSB0 aGUgbWF4X3VzYWJsZQogICAgc2hvdWxkIGJlIGNhcHBlZCwgYWZ0ZXIgYSBzdWNjZXNzZnVsIGlu aXRyZCBhZGR0aW9uLgoKICAgIEN1cnJlbnRseSBtaW4vbWF4IHVzYWJsZSBpcyBzZXQgdG8gdGhl IHNhbWUgdmFsdWUsIG1ha2luZyBpdAogICAgaW1wb3NzaWJsZSBmcm9tIHN1YnNlcXVlbnQgc2Vn bWVudCBhbGxvY2F0aW9ucyB0byBzdWNjZXNzLgoKICAqIFJJU0MtVjogTWFrZSBnZXRfbWVtb3J5 X3JhbmdlcygpIHByb3Blcmx5IGV4Y2x1ZGUgIlJlc2VydmVkIgogICAgcmVnaW9ucwoKICAgIFRo ZSBnZXRfbWVtb3J5X3JhbmdlcygpIGRpZCBub3QgZXhjbHVkZSAiUmVzZXJ2ZWQiIHJlZ2lvbnMg ZnJvbQogICAgIlN5c3RlbSBSQU0iIHJlZ2lvbnMuIEl0IHNpbXBseSBhZGRlZCAiUmVzZXJ2ZWQi IGFzIElPTUVNLCBhbmQKICAgIElPTUVNIGlzIG5vdCBjb25zaWRlcmVkIHdoZW4gbG9va2luZyBm b3IgaG9sZXMgdG8gcGxhY2Uga2V4ZWMKICAgIHNlZ21lbnRzLgoKICAgIEluc3RlYWQsIGRvIGEg dHdvIHBhc3Mgb2YgdGhlIC9wcm9jL2lvbWVtIGZpbGUuIEZpcnN0IHBhc3MsIGFkZHMKICAgIGFs bCB0aGUgIlN5c3RlbSBSQU0iIG1lbW9yeSwgYW5kIHRoZSBzZWNvbmQgcGFzcyByZW1vdmVzIGFs bAogICAgaW50ZXJzZWN0aW5nICJSZXNlcnZlZCIgcmVnaW9ucy4KClsxXSBodHRwczovL2xvcmUu a2VybmVsLm9yZy9saW51eC1yaXNjdi9DQUxlY1Q1Z1FXbjBQUk80UTI0YjZxa3JmVkU1T3hzQ3A2 NVR1aFdUYjMwY2VLX09KMEFAbWFpbC5nbWFpbC5jb20vClsyXSBodHRwczovL2xvcmUua2VybmVs Lm9yZy9rZXhlYy8yMDIyMTAyMDAzMTU0OC40NzU4Ny0xLXhpYW50aW5nLnRpYW5AbGludXguYWxp YmFiYS5jb20vClszXSBodHRwczovL2dpdGh1Yi5jb20vZGV2aWNldHJlZS1vcmcvZHQtc2NoZW1h L2Jsb2IvbWFpbi9kdHNjaGVtYS9zY2hlbWFzL2Nob3Nlbi55YW1sCgpUZXN0ZWQtYnk6IFlpeHVu IExhbiA8eWl4dW4ubGFuQGdtYWlsLmNvbT4KQ28tZGV2ZWxvcGVkLWJ5OiBYaWFudGluZyBUaWFu IDx4aWFudGluZy50aWFuQGxpbnV4LmFsaWJhYmEuY29tPgpDby1kZXZlbG9wZWQtYnk6IFlpeHVu IExhbiA8eWl4dW4ubGFuQGdtYWlsLmNvbT4KU2lnbmVkLW9mZi1ieTogTmljayBLb3NzaWZpZGlz IDxtaWNrQGljcy5mb3J0aC5ncj4KU2lnbmVkLW9mZi1ieTogU2ltb24gSG9ybWFuIDxob3Jtc0Br ZXJuZWwub3JnPgpTaWduZWQtb2ZmLWJ5OiBTb25nIFNodWFpIDxzb25nc2h1YWlzaHVhaUB0aW55 bGFiLm9yZz4KU2lnbmVkLW9mZi1ieTogQmrDtnJuIFTDtnBlbCA8Ympvcm5Acml2b3NpbmMuY29t PgotLS0KIC5naXRodWIvd29ya2Zsb3dzL2J1aWxkLnltbCAgICAgICAgICAgICB8ICAgMSArCiBj b25maWd1cmUuYWMgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDMgKwogaW5jbHVkZS9l bGYuaCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAxICsKIGtleGVjL01ha2VmaWxlICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgMSArCiBrZXhlYy9hcmNoL21pcHMvTWFrZWZpbGUg ICAgICAgICAgICAgICAgfCAgIDIgKwoga2V4ZWMvYXJjaC9yaXNjdi9NYWtlZmlsZSAgICAgICAg ICAgICAgIHwgIDM2ICsrCiBrZXhlYy9hcmNoL3Jpc2N2L2NyYXNoZHVtcC1yaXNjdi5jICAgICAg fCAxNDAgKysrKysrKysKIGtleGVjL2FyY2gvcmlzY3YvaW5jbHVkZS9hcmNoL29wdGlvbnMuaCB8 ICA0MyArKysKIGtleGVjL2FyY2gvcmlzY3YvaW9tZW0uaCAgICAgICAgICAgICAgICB8ICAxMCAr CiBrZXhlYy9hcmNoL3Jpc2N2L2tleGVjLWVsZi1yaXNjdi5jICAgICAgfCAyNTUgKysrKysrKysr KysrKysKIGtleGVjL2FyY2gvcmlzY3Yva2V4ZWMtcmlzY3YuYyAgICAgICAgICB8IDQzMSArKysr KysrKysrKysrKysrKysrKysrKwoga2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5oICAgICAg ICAgIHwgIDMyICsrCiBrZXhlYy9kdC1vcHMuYyAgICAgICAgICAgICAgICAgICAgICAgICAgfCA0 NDIgKysrKysrKysrKysrKysrKysrKysrKystCiBrZXhlYy9kdC1vcHMuaCAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgIDcgKwoga2V4ZWMva2V4ZWMtc3lzY2FsbC5oICAgICAgICAgICAgICAg ICAgIHwgICA0ICsKIHB1cmdhdG9yeS9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgICB8ICAg MSArCiBwdXJnYXRvcnkvYXJjaC9yaXNjdi9NYWtlZmlsZSAgICAgICAgICAgfCAgIDcgKwogMTcg ZmlsZXMgY2hhbmdlZCwgMTQxNSBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCiBjcmVhdGUg bW9kZSAxMDA2NDQga2V4ZWMvYXJjaC9yaXNjdi9NYWtlZmlsZQogY3JlYXRlIG1vZGUgMTAwNjQ0 IGtleGVjL2FyY2gvcmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBr ZXhlYy9hcmNoL3Jpc2N2L2luY2x1ZGUvYXJjaC9vcHRpb25zLmgKIGNyZWF0ZSBtb2RlIDEwMDY0 NCBrZXhlYy9hcmNoL3Jpc2N2L2lvbWVtLmgKIGNyZWF0ZSBtb2RlIDEwMDY0NCBrZXhlYy9hcmNo L3Jpc2N2L2tleGVjLWVsZi1yaXNjdi5jCiBjcmVhdGUgbW9kZSAxMDA2NDQga2V4ZWMvYXJjaC9y aXNjdi9rZXhlYy1yaXNjdi5jCiBjcmVhdGUgbW9kZSAxMDA2NDQga2V4ZWMvYXJjaC9yaXNjdi9r ZXhlYy1yaXNjdi5oCiBjcmVhdGUgbW9kZSAxMDA2NDQgcHVyZ2F0b3J5L2FyY2gvcmlzY3YvTWFr ZWZpbGUKCmRpZmYgLS1naXQgYS8uZ2l0aHViL3dvcmtmbG93cy9idWlsZC55bWwgYi8uZ2l0aHVi L3dvcmtmbG93cy9idWlsZC55bWwKaW5kZXggNDZlZGRlNjZlMzg0Li5kZGI0YmZhOGIwMWQgMTAw NjQ0Ci0tLSBhLy5naXRodWIvd29ya2Zsb3dzL2J1aWxkLnltbAorKysgYi8uZ2l0aHViL3dvcmtm bG93cy9idWlsZC55bWwKQEAgLTE5LDYgKzE5LDcgQEAgam9iczoKICAgICAgICAgLSBwb3dlcnBj CiAgICAgICAgIC0gcG93ZXJwYzY0CiAgICAgICAgIC0gcG93ZXJwYzY0bGUKKyAgICAgICAgLSBy aXNjdjY0CiAgICAgICAgIC0gc2g0CiAgICAgICAgIC0gczM5MHgKICAgICAgICAgLSB4ODZfNjQt eDMyCmRpZmYgLS1naXQgYS9jb25maWd1cmUuYWMgYi9jb25maWd1cmUuYWMKaW5kZXggOGI3OWVl ZjlhZmViLi5jYmQ2ZWRiZDk4N2QgMTAwNjQ0Ci0tLSBhL2NvbmZpZ3VyZS5hYworKysgYi9jb25m aWd1cmUuYWMKQEAgLTYxLDYgKzYxLDkgQEAgY2FzZSAkdGFyZ2V0X2NwdSBpbgogCWxvb25nYXJj aCopCiAJCUFSQ0g9Imxvb25nYXJjaCIKIAkJOzsKKwlyaXNjdjMyfHJpc2N2NjQpCisJCUFSQ0g9 InJpc2N2IgorCQk7OwogCSogKQogCQlBQ19NU0dfRVJST1IoW3Vuc3VwcG9ydGVkIGFyY2hpdGVj dHVyZSAkdGFyZ2V0X2NwdV0pCiAJCTs7CmRpZmYgLS1naXQgYS9pbmNsdWRlL2VsZi5oIGIvaW5j bHVkZS9lbGYuaAppbmRleCAxYzhkMmNjZjZkMjYuLjkzYTVlZTVlZWZmYSAxMDA2NDQKLS0tIGEv aW5jbHVkZS9lbGYuaAorKysgYi9pbmNsdWRlL2VsZi5oCkBAIC0yNTksNiArMjU5LDcgQEAgdHlw ZWRlZiBzdHJ1Y3QKICNkZWZpbmUgRU1fQVJDX0E1CTkzCQkvKiBBUkMgQ29yZXMgVGFuZ2VudC1B NSAqLwogI2RlZmluZSBFTV9YVEVOU0EJOTQJCS8qIFRlbnNpbGljYSBYdGVuc2EgQXJjaGl0ZWN0 dXJlICovCiAjZGVmaW5lIEVNX0FBUkNINjQJMTgzCQkvKiBBUk0gQUFSQ0g2NCAqLworI2RlZmlu ZSBFTV9SSVNDVgkyNDMJCS8qIFJJU0MtViAqLwogI2RlZmluZSBFTV9MT09OR0FSQ0gJMjU4CQkv KiBMb29uZ3NvbiBMb29uZ2FyY2gqLwogI2RlZmluZSBFTV9OVU0JCTE4NAogCmRpZmYgLS1naXQg YS9rZXhlYy9NYWtlZmlsZSBiL2tleGVjL01ha2VmaWxlCmluZGV4IGU5NjlkMWUxOGM1YS4uOGI1 ODUxZGVjYWVhIDEwMDY0NAotLS0gYS9rZXhlYy9NYWtlZmlsZQorKysgYi9rZXhlYy9NYWtlZmls ZQpAQCAtOTIsNiArOTIsNyBAQCBpbmNsdWRlICQoc3JjZGlyKS9rZXhlYy9hcmNoL21pcHMvTWFr ZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL2tleGVjL2FyY2gvY3Jpcy9NYWtlZmlsZQogaW5jbHVk ZSAkKHNyY2Rpcikva2V4ZWMvYXJjaC9wcGMvTWFrZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL2tl eGVjL2FyY2gvcHBjNjQvTWFrZWZpbGUKK2luY2x1ZGUgJChzcmNkaXIpL2tleGVjL2FyY2gvcmlz Y3YvTWFrZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL2tleGVjL2FyY2gvczM5MC9NYWtlZmlsZQog aW5jbHVkZSAkKHNyY2Rpcikva2V4ZWMvYXJjaC9zaC9NYWtlZmlsZQogaW5jbHVkZSAkKHNyY2Rp cikva2V4ZWMvYXJjaC94ODZfNjQvTWFrZWZpbGUKZGlmZiAtLWdpdCBhL2tleGVjL2FyY2gvbWlw cy9NYWtlZmlsZSBiL2tleGVjL2FyY2gvbWlwcy9NYWtlZmlsZQppbmRleCAxZmU3ODg2MDhmYmUu LjBhNWNlMTkyNmRjOSAxMDA2NDQKLS0tIGEva2V4ZWMvYXJjaC9taXBzL01ha2VmaWxlCisrKyBi L2tleGVjL2FyY2gvbWlwcy9NYWtlZmlsZQpAQCAtMTMsNiArMTMsOCBAQCBtaXBzX0ZTMkRUX0lO Q0xVREUgPSBcCiAKIG1pcHNfRFRfT1BTICs9IGtleGVjL2R0LW9wcy5jCiAKK21pcHNfTUVNX1JF R0lPTlMgPSBrZXhlYy9tZW1fcmVnaW9ucy5jCisKIGluY2x1ZGUgJChzcmNkaXIpL2tleGVjL2xp YmZkdC9NYWtlZmlsZS5saWJmZHQKIAogbGliZmR0X1NSQ1MgKz0gJChMSUJGRFRfU1JDUzolPWtl eGVjL2xpYmZkdC8lKQpkaWZmIC0tZ2l0IGEva2V4ZWMvYXJjaC9yaXNjdi9NYWtlZmlsZSBiL2tl eGVjL2FyY2gvcmlzY3YvTWFrZWZpbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw MDAwMDAwLi45OTM3ZmJiNTcyNGYKLS0tIC9kZXYvbnVsbAorKysgYi9rZXhlYy9hcmNoL3Jpc2N2 L01ha2VmaWxlCkBAIC0wLDAgKzEsMzYgQEAKKyMKKyMga2V4ZWMgcmlzY3YKKyMKK3Jpc2N2X0tF WEVDX1NSQ1MgPSBrZXhlYy9hcmNoL3Jpc2N2L2NyYXNoZHVtcC1yaXNjdi5jCityaXNjdl9LRVhF Q19TUkNTICs9IGtleGVjL2FyY2gvcmlzY3Yva2V4ZWMtZWxmLXJpc2N2LmMKK3Jpc2N2X0tFWEVD X1NSQ1MgKz0ga2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5jCisKK3Jpc2N2X0RUX09QUyAr PSBrZXhlYy9kdC1vcHMuYworCityaXNjdl9NRU1fUkVHSU9OUyA9IGtleGVjL21lbV9yZWdpb25z LmMKKworcmlzY3ZfQVJDSF9SRVVTRV9JTklUUkQgPQorCityaXNjdl9DUFBGTEFHUyArPSAtSSAk KHNyY2Rpcikva2V4ZWMvCisKK2Rpc3QgKz0gJChyaXNjdl9LRVhFQ19TUkNTKQkJCQlcCisJa2V4 ZWMvYXJjaC9yaXNjdi9pbmNsdWRlL2FyY2gvb3B0aW9ucy5oCQlcCisJa2V4ZWMvYXJjaC9yaXNj di9pb21lbS5oCQkJXAorCWtleGVjL2FyY2gvcmlzY3Yva2V4ZWMtcmlzY3YuaAkJCVwKKwlrZXhl Yy9hcmNoL3Jpc2N2L01ha2VmaWxlCisKK2lmZGVmIEhBVkVfTElCRkRUCisKK0xJQlMgKz0gLWxm ZHQKKworZWxzZQorCitpbmNsdWRlICQoc3JjZGlyKS9rZXhlYy9saWJmZHQvTWFrZWZpbGUubGli ZmR0CisKK2xpYmZkdF9TUkNTICs9ICQoTElCRkRUX1NSQ1M6JT1rZXhlYy9saWJmZHQvJSkKKwor cmlzY3ZfQ1BQRkxBR1MgKz0gLUkkKHNyY2Rpcikva2V4ZWMvbGliZmR0CisKK3Jpc2N2X0tFWEVD X1NSQ1MgKz0gJChsaWJmZHRfU1JDUykKKworZW5kaWYKZGlmZiAtLWdpdCBhL2tleGVjL2FyY2gv cmlzY3YvY3Jhc2hkdW1wLXJpc2N2LmMgYi9rZXhlYy9hcmNoL3Jpc2N2L2NyYXNoZHVtcC1yaXNj di5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMzM2ZDdhN2Y1NjQ2 Ci0tLSAvZGV2L251bGwKKysrIGIva2V4ZWMvYXJjaC9yaXNjdi9jcmFzaGR1bXAtcmlzY3YuYwpA QCAtMCwwICsxLDE0MCBAQAorI2luY2x1ZGUgPGVycm5vLmg+CisjaW5jbHVkZSA8ZWxmLmg+Cisj aW5jbHVkZSA8dW5pc3RkLmg+CisKKyNpbmNsdWRlICJrZXhlYy5oIgorI2luY2x1ZGUgImNyYXNo ZHVtcC5oIgorI2luY2x1ZGUgImtleGVjLWVsZi5oIgorI2luY2x1ZGUgIm1lbV9yZWdpb25zLmgi CisKK3N0YXRpYyBzdHJ1Y3QgY3Jhc2hfZWxmX2luZm8gZWxmX2luZm8gPSB7CisjaWYgX19yaXNj dl94bGVuID09IDY0CisJLmNsYXNzCQk9IEVMRkNMQVNTNjQsCisjZWxzZQorCS5jbGFzcwkJPSBF TEZDTEFTUzMyLAorI2VuZGlmCisJLmRhdGEJCT0gRUxGREFUQTJMU0IsCisJLm1hY2hpbmUJPSBF TV9SSVNDViwKK307CisKK3N0YXRpYyBzdHJ1Y3QgbWVtb3J5X3JhbmdlcyBjcmFzaF9tZW1fcmFu Z2VzID0gezB9Oworc3RydWN0IG1lbW9yeV9yYW5nZSBlbGZjb3JlaGRyX21lbSA9IHswfTsKKwor c3RhdGljIHVuc2lnbmVkIGxvbmcgbG9uZyBnZXRfcGFnZV9vZmZzZXQoc3RydWN0IGtleGVjX2lu Zm8gKmluZm8pCit7CisJdW5zaWduZWQgbG9uZyBsb25nIHZhZGRyX29mZiA9IDA7CisJdW5zaWdu ZWQgbG9uZyBsb25nIHBhZ2Vfc2l6ZSA9IHN5c2NvbmYoX1NDX1BBR0VTSVpFKTsKKwl1bnNpZ25l ZCBsb25nIGxvbmcgaW5pdF9zdGFydCA9IGdldF9rZXJuZWxfc3ltKCJfc2luaXR0ZXh0Iik7CisK KwkvKgorCSAqIEJlZ2luaW5nIG9mIGluaXQgc2VjdGlvbiBpcyBhbGlnbmVkIHRvIHBhZ2Ugc2l6 ZQorCSAqLworCXZhZGRyX29mZiA9IGluaXRfc3RhcnQgLSBwYWdlX3NpemU7CisKKwlyZXR1cm4g dmFkZHJfb2ZmOworfQorCitpbnQgbG9hZF9lbGZjb3JlaGRyKHN0cnVjdCBrZXhlY19pbmZvICpp bmZvKQoreworCXN0cnVjdCBtZW1vcnlfcmFuZ2UgY3Jhc2hrZXJuX3JhbmdlID0gezB9OworCXN0 cnVjdCBtZW1vcnlfcmFuZ2UgKnJhbmdlcyA9IE5VTEw7CisJdW5zaWduZWQgbG9uZyBzdGFydCA9 IDA7CisJdW5zaWduZWQgbG9uZyBlbmQgPSAwOworCXVuc2lnbmVkIGxvbmcgYnVmX3NpemUgPSAw OworCXVuc2lnbmVkIGxvbmcgZWxmY29yZWhkcl9hZGRyID0gMDsKKwl2b2lkKiBidWYgPSBOVUxM OworCWludCBpID0gMDsKKwlpbnQgcmV0ID0gMDsKKworCXJldCA9IHBhcnNlX2lvbWVtX3Npbmds ZSgiS2VybmVsIGNvZGVcbiIsICZzdGFydCwgTlVMTCk7CisJaWYgKHJldCkgeworCQlmcHJpbnRm KHN0ZGVyciwgIkNhbm5vdCBkZXRlcm1pbmUga2VybmVsIHBoeXNpY2FsIGJhc2UgYWRkclxuIik7 CisJCXJldHVybiAtRUlOVkFMOworCX0KKwllbGZfaW5mby5rZXJuX3BhZGRyX3N0YXJ0ID0gc3Rh cnQ7CisKKwlyZXQgPSBwYXJzZV9pb21lbV9zaW5nbGUoIktlcm5lbCBic3NcbiIsIE5VTEwsICZl bmQpOworCWlmIChyZXQpIHsKKwkJZnByaW50ZihzdGRlcnIsICJDYW5ub3QgZGV0ZXJtaW5lIGtl cm5lbCBwaHlzaWNhbCBic3MgYWRkclxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKwllbGZf aW5mby5rZXJuX3BhZGRyX3N0YXJ0ID0gc3RhcnQ7CisJZWxmX2luZm8ua2Vybl9zaXplID0gZW5k IC0gc3RhcnQ7CisKKwllbGZfaW5mby5rZXJuX3ZhZGRyX3N0YXJ0ID0gZ2V0X2tlcm5lbF9zeW0o Il90ZXh0Iik7CisJaWYgKCFlbGZfaW5mby5rZXJuX3ZhZGRyX3N0YXJ0KSB7CisJCWVsZl9pbmZv Lmtlcm5fdmFkZHJfc3RhcnQgPSBVSU5UNjRfTUFYOworCX0KKworCWVsZl9pbmZvLnBhZ2Vfb2Zm c2V0ID0gZ2V0X3BhZ2Vfb2Zmc2V0KGluZm8pOworCWRiZ3ByaW50ZigicGFnZV9vZmZzZXQ6ICAg JTAxNmxseFxuIiwgZWxmX2luZm8ucGFnZV9vZmZzZXQpOworCisJcmV0ID0gcGFyc2VfaW9tZW1f c2luZ2xlKCJDcmFzaCBrZXJuZWxcbiIsICZzdGFydCwgJmVuZCk7CisJaWYgKHJldCkgeworCQlm cHJpbnRmKHN0ZGVyciwgIkNhbm5vdCBkZXRlcm1pbmUga2VybmVsIHBoeXNpY2FsIGJzcyBhZGRy XG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCWNyYXNoa2Vybl9yYW5nZS5zdGFydCA9IHN0 YXJ0OworCWNyYXNoa2Vybl9yYW5nZS5lbmQgPSBlbmQ7CisJY3Jhc2hrZXJuX3JhbmdlLnR5cGUg PSBSQU5HRV9SRVNFUlZFRDsKKworCXJhbmdlcyA9IGluZm8tPm1lbW9yeV9yYW5nZTsKKwlmb3Ig KGkgPSAwOyBpIDwgaW5mby0+bWVtb3J5X3JhbmdlczsgaSsrKSB7CisJCXJldCA9IG1lbV9yZWdp b25zX2FsbG9jX2FuZF9hZGQoJmNyYXNoX21lbV9yYW5nZXMsCisJCQkJCQlyYW5nZXNbaV0uc3Rh cnQsCisJCQkJCQlyYW5nZXNbaV0uZW5kIC0gcmFuZ2VzW2ldLnN0YXJ0ICsgMSwKKwkJCQkJCXJh bmdlc1tpXS50eXBlKTsKKwkJaWYgKHJldCApIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiQ291bGQg bm90IGNyZWF0ZSBjcmFzaF9tZW1fcmFuZ2VzXG4iKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKwl9 CisKKwlyZXQgPSBtZW1fcmVnaW9uc19hbGxvY19hbmRfZXhjbHVkZSgmY3Jhc2hfbWVtX3Jhbmdl cywKKwkJCQkJICAgICZjcmFzaGtlcm5fcmFuZ2UpOworCWlmIChyZXQpIHsKKwkJZnByaW50Zihz dGRlcnIsICJDb3VsZCBub3QgZXhjbHVkZSBjcmFzaGtlcm5fcmFuZ2VcbiIpOworCQlyZXR1cm4g cmV0OworCX0KKworI2lmIF9fcmlzY3ZfeGxlbiA9PSA2NAorCWNyYXNoX2NyZWF0ZV9lbGY2NF9o ZWFkZXJzKGluZm8sICZlbGZfaW5mbywgY3Jhc2hfbWVtX3Jhbmdlcy5yYW5nZXMsCisJCQkJICAg Y3Jhc2hfbWVtX3Jhbmdlcy5zaXplLCAmYnVmLCAmYnVmX3NpemUsCisJCQkJICAgRUxGX0NPUkVf SEVBREVSX0FMSUdOKTsKKworI2Vsc2UKKwljcmFzaF9jcmVhdGVfZWxmMzJfaGVhZGVycyhpbmZv LCAmZWxmX2luZm8sIGNyYXNoX21lbV9yYW5nZXMucmFuZ2VzLAorCQkJCSAgIGNyYXNoX21lbV9y YW5nZXMuc2l6ZSwgJmJ1ZiwgJmJ1Zl9zaXplLAorCQkJCSAgIEVMRl9DT1JFX0hFQURFUl9BTElH Tik7CisjZW5kaWYKKworCisJZWxmY29yZWhkcl9hZGRyID0gYWRkX2J1ZmZlcl9waHlzX3ZpcnQo aW5mbywgYnVmLCBidWZfc2l6ZSwKKwkJCQkJICAgICAgIGJ1Zl9zaXplLCAwLAorCQkJCQkgICAg ICAgY3Jhc2hrZXJuX3JhbmdlLnN0YXJ0LAorCQkJCQkgICAgICAgY3Jhc2hrZXJuX3JhbmdlLmVu ZCwKKwkJCQkJICAgICAgIC0xLCAwKTsKKworCWVsZmNvcmVoZHJfbWVtLnN0YXJ0ID0gZWxmY29y ZWhkcl9hZGRyOworCWVsZmNvcmVoZHJfbWVtLmVuZCA9IGVsZmNvcmVoZHJfYWRkciArIGJ1Zl9z aXplIC0gMTsKKworCWRiZ3ByaW50ZigiJXM6IGVsZmNvcmVoZHIgMHglbGx4LTB4JWxseFxuIiwg X19mdW5jX18sCisJCSAgZWxmY29yZWhkcl9tZW0uc3RhcnQsIGVsZmNvcmVoZHJfbWVtLmVuZCk7 CisKKwlyZXR1cm4gMDsKK30KKworaW50IGlzX2NyYXNoa2VybmVsX21lbV9yZXNlcnZlZCh2b2lk KQoreworCXVpbnQ2NF90IHN0YXJ0ID0gMDsKKwl1aW50NjRfdCBlbmQgPSAwOworCisJcmV0dXJu IHBhcnNlX2lvbWVtX3NpbmdsZSgiQ3Jhc2gga2VybmVsXG4iLCAmc3RhcnQsICZlbmQpID09IDAg PworCSAgICAgICAoc3RhcnQgIT0gZW5kKSA6IDA7Cit9CisKK2ludCBnZXRfY3Jhc2hfa2VybmVs X2xvYWRfcmFuZ2UodWludDY0X3QgKnN0YXJ0LCB1aW50NjRfdCAqZW5kKQoreworCXJldHVybiBw YXJzZV9pb21lbV9zaW5nbGUoIkNyYXNoIGtlcm5lbFxuIiwgc3RhcnQsIGVuZCk7Cit9CisKZGlm ZiAtLWdpdCBhL2tleGVjL2FyY2gvcmlzY3YvaW5jbHVkZS9hcmNoL29wdGlvbnMuaCBiL2tleGVj L2FyY2gvcmlzY3YvaW5jbHVkZS9hcmNoL29wdGlvbnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NApp bmRleCAwMDAwMDAwMDAwMDAuLjdjMjQxODRiMWYzZQotLS0gL2Rldi9udWxsCisrKyBiL2tleGVj L2FyY2gvcmlzY3YvaW5jbHVkZS9hcmNoL29wdGlvbnMuaApAQCAtMCwwICsxLDQzIEBACisjaWZu ZGVmIEtFWEVDX0FSQ0hfUklTQ1ZfT1BUSU9OU19ICisjZGVmaW5lIEtFWEVDX0FSQ0hfUklTQ1Zf T1BUSU9OU19ICisKKyNkZWZpbmUgT1BUX0FQUEVORAkJKChPUFRfTUFYKSswKQorI2RlZmluZSBP UFRfRFRCCQkJKChPUFRfTUFYKSsxKQorI2RlZmluZSBPUFRfSU5JVFJECQkoKE9QVF9NQVgpKzIp CisjZGVmaW5lIE9QVF9DTURMSU5FCQkoKE9QVF9NQVgpKzMpCisjZGVmaW5lIE9QVF9SRVVTRV9D TURMSU5FCSgoT1BUX01BWCkrNCkKKyNkZWZpbmUgT1BUX0FSQ0hfTUFYCQkoKE9QVF9NQVgpKzUp CisKKy8qIE9wdGlvbnMgcmVsZXZhbnQgdG8gdGhlIGFyY2hpdGVjdHVyZSAoZXhjbHVkaW5nIGxv YWRlci1zcGVjaWZpYyBvbmVzKSwKKyAqIGluIHRoaXMgY2FzZSBub25lOgorICovCisjZGVmaW5l IEtFWEVDX0FSQ0hfT1BUSU9OUyBcCisJS0VYRUNfT1BUSU9OUyBcCisJeyAiYXBwZW5kIiwJCTEs IDAsIE9QVF9BUFBFTkR9LCBcCisJeyAiZHRiIiwJCTEsIDAsIE9QVF9EVEIgfSwgXAorCXsgImlu aXRyZCIsCQkxLCAwLCBPUFRfSU5JVFJEIH0sIFwKKwl7ICJjb21tYW5kLWxpbmUiLAkxLCAwLCBP UFRfQ01ETElORX0sIFwKKwl7ICJyZXVzZS1jbWRsaW5lIiwJMCwgTlVMTCwgT1BUX1JFVVNFX0NN RExJTkUgfSwgXAorCisKKyNkZWZpbmUgS0VYRUNfQVJDSF9PUFRfU1RSIEtFWEVDX09QVF9TVFIg IiIKKworLyogVGhlIGZvbGxvd2luZyB0d28gI2RlZmluZXMgbGlzdCBBTEwgb2YgdGhlIG9wdGlv bnMgYWRkZWQgYnkgYWxsIG9mIHRoZQorICogYXJjaGl0ZWN0dXJlJ3MgbG9hZGVycy4KKyAqIG8J bWFpbigpIHVzZXMgdGhpcyBjb21wbGV0ZSBsaXN0IHRvIHNjYW4gZm9yIGl0cyBvcHRpb25zLCBp Z25vcmluZworICoJYXJjaC1zcGVjaWZpYy9sb2FkZXItc3BlY2lmaWMgb25lcy4KKyAqIG8JVGhl biwgYXJjaF9wcm9jZXNzX29wdGlvbnMoKSB1c2VzIHRoaXMgY29tcGxldGUgbGlzdCB0byBzY2Fu IGZvciBpdHMKKyAqCW9wdGlvbnMsIGlnbm9yaW5nIGdlbmVyYWwvbG9hZGVyLXNwZWNpZmljIG9u ZXMuCisgKiBvCVRoZW4sIHRoZSBmaWxlX3R5cGVbbl0ubG9hZCByZS1zY2FucyBmb3Igb3B0aW9u cywgdXNpbmcKKyAqCUtFWEVDX0FSQ0hfT1BUSU9OUyBwbHVzIGl0cyBsb2FkZXItc3BlY2lmaWMg b3B0aW9ucyBzdWJzZXQuCisgKglBbnkgdW5yZWNvZ25pc2VkIG9wdGlvbnMgY2F1c2UgYW4gZXJy b3IgaGVyZS4KKyAqCisgKiBUaGlzIGlzIGRvbmUgc28gdGhhdCBtYWluKCkncy9hcmNoX3Byb2Nl c3Nfb3B0aW9ucygpJ3MgZ2V0b3B0X2xvbmcoKSBjYWxscworICogZG9uJ3QgY2hvb3NlIGEga2Vy bmVsIGZpbGVuYW1lIGZyb20gcmFuZG9tIGFyZ3VtZW50cyB0byBvcHRpb25zIHRoZXkgZG9uJ3QK KyAqIHJlY29nbmlzZSAtLSBhcyB0aGV5IG5vdyByZWNvZ25pc2UgKGlmIG5vdCBhY3QgdXBvbikg YWxsIHBvc3NpYmxlIG9wdGlvbnMuCisgKi8KKyNkZWZpbmUgS0VYRUNfQUxMX09QVElPTlMgS0VY RUNfQVJDSF9PUFRJT05TCisKKyNkZWZpbmUgS0VYRUNfQUxMX09QVF9TVFIgS0VYRUNfQVJDSF9P UFRfU1RSCisKKyNlbmRpZiAvKiBLRVhFQ19BUkNIX1JJU0NWX09QVElPTlNfSCAqLwpkaWZmIC0t Z2l0IGEva2V4ZWMvYXJjaC9yaXNjdi9pb21lbS5oIGIva2V4ZWMvYXJjaC9yaXNjdi9pb21lbS5o Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uNzY3MWUyNmE5NTk0Ci0t LSAvZGV2L251bGwKKysrIGIva2V4ZWMvYXJjaC9yaXNjdi9pb21lbS5oCkBAIC0wLDAgKzEsMTAg QEAKKyNpZm5kZWYgSU9NRU1fSAorI2RlZmluZSBJT01FTV9ICisKKyNkZWZpbmUgU1lTVEVNX1JB TQkJIlN5c3RlbSBSQU1cbiIKKyNkZWZpbmUgS0VSTkVMX0NPREUJCSJLZXJuZWwgY29kZVxuIgor I2RlZmluZSBLRVJORUxfREFUQQkJIktlcm5lbCBkYXRhXG4iCisjZGVmaW5lIENSQVNIX0tFUk5F TAkJIkNyYXNoIGtlcm5lbFxuIgorI2RlZmluZSBJT01FTV9SRVNFUlZFRAkJIlJlc2VydmVkXG4i CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEva2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1lbGYtcmlzY3Yu YyBiL2tleGVjL2FyY2gvcmlzY3Yva2V4ZWMtZWxmLXJpc2N2LmMKbmV3IGZpbGUgbW9kZSAxMDA2 NDQKaW5kZXggMDAwMDAwMDAwMDAwLi5mM2MwMTFjNGMxZGMKLS0tIC9kZXYvbnVsbAorKysgYi9r ZXhlYy9hcmNoL3Jpc2N2L2tleGVjLWVsZi1yaXNjdi5jCkBAIC0wLDAgKzEsMjU1IEBACisvKiBT UERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCAqLworLyoKKyAqIENvcHlyaWdodCAoQykg MjAxOSBGT1JUSC1JQ1MvQ0FSVgorICogICAgICAgICAgICAgIE5pY2sgS29zc2lmaWRpcyA8bWlj a0BpY3MuZm9ydGguZ3I+CisgKi8KKworI2luY2x1ZGUgImtleGVjLmgiCisjaW5jbHVkZSAiZHQt b3BzLmgiCQkvKiBGb3IgZHRiX3NldC9jbGVhcl9pbml0cmQoKSAqLworI2luY2x1ZGUgPGVsZi5o PgkJLyogRm9yIEVMRiBoZWFkZXIgaGFuZGxpbmcgKi8KKyNpbmNsdWRlIDxlcnJuby5oPgkJLyog Rm9yIEVGQklHL0VJTlZBTCAqLworI2luY2x1ZGUgPHVuaXN0ZC5oPgkJLyogRm9yIGdldHBhZ2Vz aXplKCkgKi8KKyNpbmNsdWRlICJrZXhlYy1zeXNjYWxsLmgiCS8qIEZvciBLRVhFQ19PTl9DUkFT SCAqLworI2luY2x1ZGUgImtleGVjLXJpc2N2LmgiCisKKworLyoqKioqKioqKlwKKyogSEVMUEVS UyAqCitcKioqKioqKioqLworCisvKgorICogR28gdGhyb3VnaCB0aGUgYXZhaWxhYmxlIHBoeXNp Y2FsIG1lbW9yeSByZWdpb25zIGFuZAorICogZmluZCBvbmUgdGhhdCBjYW4gaG9sZCBhbiBpbWFn ZSBvZiB0aGUgc3BlY2lmaWVkIHNpemUuCisgKiBOb3RlOiBUaGlzIGlzIGNhbGxlZCBhZnRlciBn ZXRfbWVtb3J5X3JhbmdlcyBzbworICogaW5mby0+bWVtb3J5X3JhbmdlW10gc2hvdWxkIGJlIHBv cHVsYXRlZC4gQWxzbyBub3RlIHRoYXQKKyAqIG1lbW9yeSByYW5nZXMgYXJlIHNvcnRlZCwgc28g d2UnbGwgcmV0dXJuIHRoZSBmaXJzdCByZWdpb24KKyAqIHRoYXQncyBiaWcgZW5vdWdoIGZvciBo b2xkaW5nIHRoZSBpbWFnZS4KKyAqLworc3RhdGljIGludCBlbGZfcmlzY3ZfZmluZF9wYmFzZShz dHJ1Y3Qga2V4ZWNfaW5mbyAqaW5mbywgb2ZmX3QgKmFkZHIsCisJCQkJb2ZmX3Qgc2l6ZSkKK3sK KwlpbnQgaSA9IDA7CisJb2ZmX3Qgc3RhcnQgPSAwOworCW9mZl90IGVuZCA9IDA7CisJaW50IHJl dCA9IDA7CisKKwkvKgorCSAqIElmIHRoaXMgaW1hZ2UgaXMgZm9yIGEgY3Jhc2gga2VybmVsLCB1 c2UgdGhlIHJlZ2lvbgorCSAqIHRoZSBwcmltYXJ5IGtlcm5lbCBoYXMgYWxyZWFkeSByZXNlcnZl ZCBmb3IgdXMuCisJICovCisJaWYgKGluZm8tPmtleGVjX2ZsYWdzICYgS0VYRUNfT05fQ1JBU0gp IHsKKwkJcmV0ID0gZ2V0X2NyYXNoX2tlcm5lbF9sb2FkX3JhbmdlKCh1aW50NjRfdCAqKSAmc3Rh cnQsCisJCQkJCQkgICh1aW50NjRfdCAqKSAmZW5kKTsKKwkJaWYgKCFyZXQpIHsKKwkJCS8qCisJ CQkgKiBLZXJuZWwgc2hvdWxkIGJlIGFsaWduZWQgdG8gdGhlIG5lYXJlc3QKKwkJCSAqIGh1Z2Vw YWdlICgyTUIgZm9yIFJWNjQsIDRNQiBmb3IgUlYzMikuCisJCQkgKi8KKyNpZiBfX3Jpc2N2X3hs ZW4gPT0gNjQKKwkJCXN0YXJ0ID0gX0FMSUdOX1VQKHN0YXJ0LCAweDIwMDAwMCk7CisjZWxzZQor CQkJc3RhcnQgPSBfQUxJR05fVVAoc3RhcnQsIDB4NDAwMDAwKTsKKyNlbmRpZgorCQkJaWYgKGVu ZCA+IHN0YXJ0ICYmICgoZW5kIC0gc3RhcnQpID49IHNpemUpKSB7CisJCQkJKmFkZHIgPSBzdGFy dDsKKwkJCQlyZXR1cm4gMDsKKwkJCX0KKworCQkJcmV0dXJuIC1FRkJJRzsKKwkJfSBlbHNlCisJ CQlyZXR1cm4gRU5PQ1JBU0hLRVJORUw7CisJfQorCisJZm9yIChpID0gMDsgaSA8IGluZm8tPm1l bW9yeV9yYW5nZXM7IGkrKykgeworCQlpZiAoaW5mby0+bWVtb3J5X3JhbmdlW2ldLnR5cGUgIT0g UkFOR0VfUkFNKQorCQkJY29udGludWU7CisKKwkJc3RhcnQgPSBpbmZvLT5tZW1vcnlfcmFuZ2Vb aV0uc3RhcnQ7CisJCWVuZCA9IGluZm8tPm1lbW9yeV9yYW5nZVtpXS5lbmQ7CisKKyNpZiBfX3Jp c2N2X3hsZW4gPT0gNjQKKwkJc3RhcnQgPSBfQUxJR05fVVAoc3RhcnQsIDB4MjAwMDAwKTsKKyNl bHNlCisJCXN0YXJ0ID0gX0FMSUdOX1VQKHN0YXJ0LCAweDQwMDAwMCk7CisjZW5kaWYKKworCQlp ZiAoZW5kID4gc3RhcnQgJiYgKChlbmQgLSBzdGFydCkgPj0gc2l6ZSkpIHsKKwkJCSphZGRyID0g c3RhcnQ7CisJCQlyZXR1cm4gMDsKKwkJfQorCX0KKworCXJldHVybiAtRUZCSUc7Cit9CisKKy8q KioqKioqKioqKioqKlwKKyogRU5UUlkgUE9JTlRTICoKK1wqKioqKioqKioqKioqKi8KKworaW50 IGVsZl9yaXNjdl9wcm9iZShjb25zdCBjaGFyICpidWYsIG9mZl90IGxlbikKK3sKKwlzdHJ1Y3Qg bWVtX2VoZHIgZWhkciA9IHswfTsKKwlpbnQgcmV0ID0gMDsKKworCXJldCA9IGJ1aWxkX2VsZl9l eGVjX2luZm8oYnVmLCBsZW4sICZlaGRyLCAwKTsKKwlpZiAocmV0IDwgMCkKKwkJZ290byBjbGVh bnVwOworCisJaWYgKGVoZHIuZV9tYWNoaW5lICE9IEVNX1JJU0NWKSB7CisJCWZwcmludGYoc3Rk ZXJyLCAiTm90IGZvciB0aGlzIGFyY2hpdGVjdHVyZS5cbiIpOworCQlyZXQgPSAtRUlOVkFMOwor CQlnb3RvIGNsZWFudXA7CisJfQorCisJcmV0ID0gMDsKKworIGNsZWFudXA6CisJZnJlZV9lbGZf aW5mbygmZWhkcik7CisJcmV0dXJuIHJldDsKK30KKwordm9pZCBlbGZfcmlzY3ZfdXNhZ2Uodm9p ZCkKK3sKK30KKworaW50IGVsZl9yaXNjdl9sb2FkKGludCBhcmdjLCBjaGFyICoqYXJndiwgY29u c3QgY2hhciAqYnVmLCBvZmZfdCBsZW4sCisJCSAgIHN0cnVjdCBrZXhlY19pbmZvICppbmZvKQor eworCXN0cnVjdCBtZW1fZWhkciBlaGRyID0gezB9OworCXN0cnVjdCBtZW1fcGhkciAqcGhkciA9 IE5VTEw7CisJb2ZmX3QgbmV3X2Jhc2VfYWRkciA9IDA7CisJb2ZmX3Qga2VybmVsX3NpemUgPSAw OworCW9mZl90IHBhZ2Vfc2l6ZSA9IGdldHBhZ2VzaXplKCk7CisJb2ZmX3QgbWF4X2FkZHIgPSAw OworCW9mZl90IG9sZF9iYXNlX2FkZHIgPSAwOworCW9mZl90IG9sZF9zdGFydF9hZGRyID0gMDsK KwlpbnQgaSA9IDA7CisJaW50IHJldCA9IDA7CisKKwlpZiAoaW5mby0+ZmlsZV9tb2RlKSB7CisJ CWZwcmludGYoc3RkZXJyLCAia2V4ZWNfZmlsZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgIgorCQkJ CSJhcmNoaXRlY3R1cmVcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwkvKiBQYXJzZSB0 aGUgRUxGIGZpbGUgKi8KKwlyZXQgPSBidWlsZF9lbGZfZXhlY19pbmZvKGJ1ZiwgbGVuLCAmZWhk ciwgMCk7CisJaWYgKHJldCA8IDApIHsKKwkJZnByaW50ZihzdGRlcnIsICJFTEYgZXhlYyBwYXJz ZSBmYWlsZWRcbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwltYXhfYWRkciA9IGVsZl9t YXhfYWRkcigmZWhkcik7CisJb2xkX2Jhc2VfYWRkciA9IG1heF9hZGRyOworCW9sZF9zdGFydF9h ZGRyID0gbWF4X2FkZHI7CisKKwkvKgorCSAqIEdldCB0aGUgbWVtb3J5IGZvb3RwcmludCwgYmFz ZSBwaHlzaWNhbAorCSAqIGFuZCBzdGFydCBhZGRyZXNzIG9mIHRoZSBFTEYgaW1hZ2UKKwkgKi8K Kwlmb3IgKGkgPSAwOyBpIDwgZWhkci5lX3BobnVtOyBpKyspIHsKKwkJcGhkciA9ICZlaGRyLmVf cGhkcltpXTsKKwkJaWYgKHBoZHItPnBfdHlwZSAhPSBQVF9MT0FEKQorCQkJY29udGludWU7CisK KwkJLyoKKwkJICogTm90ZTogQWNjb3JkaW5nIHRvIEVMRiBzcGVjIHRoZSBsb2FkYWJsZSByZWdp b25zCisJCSAqIGFyZSBzb3J0ZWQgb24gcF92YWRkciwgbm90IHBfcGFkZHIuCisJCSAqLworCQlp ZiAob2xkX2Jhc2VfYWRkciA+IHBoZHItPnBfcGFkZHIpCisJCQlvbGRfYmFzZV9hZGRyID0gcGhk ci0+cF9wYWRkcjsKKworCQlpZiAocGhkci0+cF92YWRkciA9PSBlaGRyLmVfZW50cnkgfHwKKwkJ ICAgIHBoZHItPnBfcGFkZHIgPT0gZWhkci5lX2VudHJ5KQorCQkJb2xkX3N0YXJ0X2FkZHIgPSBw aGRyLT5wX3BhZGRyOworCisJCWtlcm5lbF9zaXplICs9IF9BTElHTl9VUChwaGRyLT5wX21lbXN6 LCBwYWdlX3NpemUpOworCX0KKworCWlmIChvbGRfYmFzZV9hZGRyID09IG1heF9hZGRyIHx8IGtl cm5lbF9zaXplID09IDApIHsKKwkJZnByaW50ZihzdGRlcnIsICJObyBsb2FkYWJsZSBzZWdtZW50 cyBwcmVzZW50IG9uIHRoZSAiCisJCQkJInByb3ZpZGVkIEVMRiBpbWFnZVxuIik7CisJCXJldHVy biAtRUlOVkFMOworCX0KKworCWlmIChvbGRfc3RhcnRfYWRkciA9PSBtYXhfYWRkcikgeworCQlm cHJpbnRmKHN0ZGVyciwgIkNvdWxkIG5vdCBmaW5kIHRoZSBlbnRyeSBwb2ludCBhZGRyZXNzIG9m ICIKKwkJCQkicHJvdmlkZWQgRUxGIGltYWdlXG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQor CisJZGJncHJpbnRmKCJHb3QgRUxGIHdpdGggdG90YWwgbWVtc3ogJWx1S0JcbiIKKwkJICAiQmFz ZSBwYWRkcjogMHglbFgsIHN0YXJ0X2FkZHI6IDB4JWxYXG4iLAorCQkgIGtlcm5lbF9zaXplIC8g MTAyNCwgb2xkX2Jhc2VfYWRkciwgb2xkX3N0YXJ0X2FkZHIpOworCisJLyogR2V0IGEgY29udGlu dW91cyBwaHlzaWNhbCByZWdpb24gdGhhdCBjYW4gaG9sZCB0aGUga2VybmVsICovCisJcmV0ID0g ZWxmX3Jpc2N2X2ZpbmRfcGJhc2UoaW5mbywgJm5ld19iYXNlX2FkZHIsIGtlcm5lbF9zaXplKTsK KwlpZiAocmV0IDwgMCkgeworCQlmcHJpbnRmKHN0ZGVyciwgIkNvdWxkIG5vdCBmaW5kIGEgbWVt b3J5IHJlZ2lvbiBmb3IgdGhlICIKKwkJCQkicHJvdmlkZWQgRUxGIGltYWdlXG4iKTsKKwkJcmV0 dXJuIHJldDsKKwl9CisKKwlkYmdwcmludGYoIk5ldyBiYXNlIHBhZGRyIGZvciB0aGUgRUxGOiAw eCVsWFxuIiwgbmV3X2Jhc2VfYWRkcik7CisKKwkvKiBSZS1zZXQgdGhlIGJhc2UgcGh5c2ljYWwg YWRkcmVzcyBvZiB0aGUgRUxGICovCisJZm9yIChpID0gMDsgaSA8IGVoZHIuZV9waG51bTsgaSsr KSB7CisJCXBoZHIgPSAmZWhkci5lX3BoZHJbaV07CisJCWlmIChwaGRyLT5wX3R5cGUgIT0gUFRf TE9BRCkKKwkJCWNvbnRpbnVlOworCisJCXBoZHItPnBfcGFkZHIgLT0gb2xkX2Jhc2VfYWRkcjsK KwkJcGhkci0+cF9wYWRkciArPSBuZXdfYmFzZV9hZGRyOworCX0KKworCS8qIFJlLXNldCB0aGUg ZW50cnkgcG9pbnQgYWRkcmVzcyAqLworCWVoZHIuZV9lbnRyeSA9IChvbGRfc3RhcnRfYWRkciAt IG9sZF9iYXNlX2FkZHIpICsgbmV3X2Jhc2VfYWRkcjsKKwlpbmZvLT5lbnRyeSA9ICh2b2lkICop IGVoZHIuZV9lbnRyeTsKKwlkYmdwcmludGYoIk5ldyBlbnRyeSBwb2ludCBmb3IgdGhlIEVMRjog MHglbGxYXG4iLCBlaGRyLmVfZW50cnkpOworCisKKwkvKiBMb2FkIHRoZSBFTEYgZXhlY3V0YWJs ZSAqLworCXJldCA9IGVsZl9leGVjX2xvYWQoJmVoZHIsIGluZm8pOworCWlmIChyZXQgPCAwKSB7 CisJCWZwcmludGYoc3RkZXJyLCAiRUxGIGV4ZWMgbG9hZCBmYWlsZWRcbiIpOworCQlyZXR1cm4g cmV0OworCX0KKworCXJldCA9IGxvYWRfZXh0cmFfc2VnbWVudHMoaW5mbywgbmV3X2Jhc2VfYWRk ciwKKwkJCQkgIGtlcm5lbF9zaXplLCBtYXhfYWRkcik7CisJcmV0dXJuIHJldDsKK30KKworCisv KioqKioqKlwKKyogU1RVQlMgKgorXCoqKioqKiovCisKK2ludCBtYWNoaW5lX3ZlcmlmeV9lbGZf cmVsKHN0cnVjdCBtZW1fZWhkciAqZWhkcikKK3sKKwlpZiAoZWhkci0+ZWlfZGF0YSAhPSBFTEZE QVRBMkxTQikKKwkJcmV0dXJuIDA7CisjaWYgX19yaXNjdl94bGVuID09IDY0CisJaWYgKGVoZHIt PmVpX2NsYXNzICE9IEVMRkNMQVNTNjQpCisjZWxzZQorCWlmIChlaGRyLT5laV9jbGFzcyAhPSBF TEZDTEFTUzMyKQorI2VuZGlmCisJCXJldHVybiAwOworCWlmIChlaGRyLT5lX21hY2hpbmUgIT0g RU1fUklTQ1YpCisJCXJldHVybiAwOworCXJldHVybiAxOworfQorCit2b2lkIG1hY2hpbmVfYXBw bHlfZWxmX3JlbChzdHJ1Y3QgbWVtX2VoZHIgKlVOVVNFRChlaGRyKSwKKwkJCSAgIHN0cnVjdCBt ZW1fc3ltICpVTlVTRUQoc3ltKSwKKwkJCSAgIHVuc2lnbmVkIGxvbmcgcl90eXBlLAorCQkJICAg dm9pZCAqVU5VU0VEKGxvY2F0aW9uKSwKKwkJCSAgIHVuc2lnbmVkIGxvbmcgVU5VU0VEKGFkZHJl c3MpLAorCQkJICAgdW5zaWduZWQgbG9uZyBVTlVTRUQodmFsdWUpKQoreworCXN3aXRjaCAocl90 eXBlKSB7CisJZGVmYXVsdDoKKwkJZGllKCJVbmtub3duIHJlbGEgcmVsb2NhdGlvbjogJWx1XG4i LCByX3R5cGUpOworCQlicmVhazsKKwl9Cit9CmRpZmYgLS1naXQgYS9rZXhlYy9hcmNoL3Jpc2N2 L2tleGVjLXJpc2N2LmMgYi9rZXhlYy9hcmNoL3Jpc2N2L2tleGVjLXJpc2N2LmMKbmV3IGZpbGUg bW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4zOGQ5YTM5NGFhZGQKLS0tIC9kZXYvbnVs bAorKysgYi9rZXhlYy9hcmNoL3Jpc2N2L2tleGVjLXJpc2N2LmMKQEAgLTAsMCArMSw0MzEgQEAK Ky8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wICovCisvKgorICogQ29weXJpZ2h0 IChDKSAyMDE5IEZPUlRILUlDUy9DQVJWCisgKiAgICAgICAgICAgICAgTmljayBLb3NzaWZpZGlz IDxtaWNrQGljcy5mb3J0aC5ncj4KKyAqLworCisjaW5jbHVkZSAia2V4ZWMtc3lzY2FsbC5oIgkv KiBGb3IgS0VYRUNfQVJDSF9SSVNDViAqLworI2luY2x1ZGUgImtleGVjLmgiCQkvKiBGb3IgT1BU X01BWCBhbmQgY29uY2F0X2NtZGxpbmUoKSAqLworI2luY2x1ZGUgIm1lbV9yZWdpb25zLmgiCS8q IEZvciBtZW1fcmVnaW9uc19zb3J0KCkgKi8KKyNpbmNsdWRlICJkdC1vcHMuaCIJCS8qIEZvciBk dGJfc2V0X2Jvb3RhcmdzKCkgKi8KKyNpbmNsdWRlIDxhcmNoL29wdGlvbnMuaD4JLyogRm9yIEtF WEVDX0FSQ0hfT1BUSU9OUyAqLworI2luY2x1ZGUgPGdldG9wdC5oPgkJLyogRm9yIHN0cnVjdCBv cHRpb24gKi8KKyNpbmNsdWRlIDxzeXMvc3RhdC5oPgkJLyogRm9yIHN0YXQoKSBhbmQgc3RydWN0 IHN0YXQgKi8KKyNpbmNsdWRlIDxzdGRsaWIuaD4JCS8qIEZvciBmcmVlKCkgKi8KKyNpbmNsdWRl IDxlcnJuby5oPgkJLyogRm9yIEVJTlZBTCAqLworI2luY2x1ZGUgPGxpYmZkdC5oPgkJLyogRm9y IERldmljZVRyZWUgaGFuZGxpbmcgKi8KKyNpbmNsdWRlICJrZXhlYy1yaXNjdi5oIgorI2luY2x1 ZGUgImlvbWVtLmgiCisjaW5jbHVkZSA8c3RkYm9vbC5oPgorCitjb25zdCBzdHJ1Y3QgYXJjaF9t YXBfZW50cnkgYXJjaGVzW10gPSB7CisJeyAicmlzY3YzMiIsIEtFWEVDX0FSQ0hfUklTQ1YgfSwK Kwl7ICJyaXNjdjY0IiwgS0VYRUNfQVJDSF9SSVNDViB9LAorCXsgTlVMTCwgMCB9LAorfTsKKwor CitzdHJ1Y3QgZmlsZV90eXBlIGZpbGVfdHlwZVtdID0geworCXsiZWxmLXJpc2N2IiwgZWxmX3Jp c2N2X3Byb2JlLCBlbGZfcmlzY3ZfbG9hZCwgZWxmX3Jpc2N2X3VzYWdlfSwKK307CitpbnQgZmls ZV90eXBlcyA9IHNpemVvZihmaWxlX3R5cGUpIC8gc2l6ZW9mKGZpbGVfdHlwZVswXSk7CisKK3N0 YXRpYyBjb25zdCBjaGFyIHJpc2N2X29wdHNfdXNhZ2VbXSA9CisiCS0tYXBwZW5kPVNUUklORwkJ QXBwZW5kIFNUUklORyB0byB0aGUga2VybmVsIGNvbW1hbmQgbGluZS5cbiIKKyIJLS1kdGI9RklM RQkJVXNlIEZJTEUgYXMgdGhlIGRldmljZSB0cmVlIGJsb2IuXG4iCisiCS0taW5pdHJkPUZJTEUJ CVVzZSBGSUxFIGFzIHRoZSBrZXJuZWwgaW5pdGlhbCByYW1kaXNrLlxuIgorIgktLWNvbW1hbmQt bGluZT1TVFJJTkcJVXNlIFNUUklORyBhcyB0aGUga2VybmVsJ3MgY29tbWFuZCBsaW5lLlxuIgor IgktLXJldXNlLWNtZGxpbmUJCVVzZSBrZXJuZWwgY29tbWFuZCBsaW5lIGZyb20gcnVubmluZyBz eXN0ZW0uXG4iOworCitzdGF0aWMgc3RydWN0IHJpc2N2X29wdHMgYXJjaF9vcHRpb25zID0gezB9 Oworc3RhdGljIHN0cnVjdCBmZHRfaW1hZ2UgcHJvdmlkZWRfZmR0ID0gezB9OworCisvKioqKioq KioqKioqKioqKlwKKyogQ09NTU9OIEhFTFBFUlMgKgorXCoqKioqKioqKioqKioqKiovCisKK2lu dCBsb2FkX2V4dHJhX3NlZ21lbnRzKHN0cnVjdCBrZXhlY19pbmZvICppbmZvLCB1aW50NjRfdCBr ZXJuZWxfYmFzZSwKKwkJCXVpbnQ2NF90IGtlcm5lbF9zaXplLCB1aW50NjRfdCBtYXhfYWRkcikK K3sKKwlzdHJ1Y3QgZmR0X2ltYWdlICpmZHQgPSBhcmNoX29wdGlvbnMuZmR0OworCWNoYXIgKmlu aXRyZF9idWYgPSBOVUxMOworCW9mZl90IGluaXRyZF9zaXplID0gMDsKKwl1aW50NjRfdCBpbml0 cmRfYmFzZSA9IDA7CisJdWludDY0X3Qgc3RhcnQgPSAwOworCXVpbnQ2NF90IGVuZCA9IDA7CisJ dWludDY0X3QgbWluX3VzYWJsZSA9IGtlcm5lbF9iYXNlICsga2VybmVsX3NpemU7CisJdWludDY0 X3QgbWF4X3VzYWJsZSA9IG1heF9hZGRyOworCWludCByZXQgPSAwOworCisJLyogUHJlcGFyZSB0 aGUgZGV2aWNlIHRyZWUgKi8KKwlpZiAoaW5mby0+a2V4ZWNfZmxhZ3MgJiBLRVhFQ19PTl9DUkFT SCkgeworCQlyZXQgPSBsb2FkX2VsZmNvcmVoZHIoaW5mbyk7CisJCWlmIChyZXQpIHsKKwkJCWZw cmludGYoc3RkZXJyLCAiQ291bGRuJ3QgY3JlYXRlIGVsZmNvcmVoZHJcbiIpOworCQkJcmV0dXJu IHJldDsKKwkJfQorCisJCXJldCA9IGR0Yl9hZGRfcmFuZ2VfcHJvcGVydHkoJmZkdC0+YnVmLCAm ZmR0LT5zaXplLAorCQkJCQkgICAgIGVsZmNvcmVoZHJfbWVtLnN0YXJ0LCBlbGZjb3JlaGRyX21l bS5lbmQsCisJCQkJCSAgICAgImNob3NlbiIsICJsaW51eCxlbGZjb3JlaGRyIik7CisJCWlmIChy ZXQpIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiQ291bGRuJ3QgYWRkIGVsZmNvcmVoZHIgdG8gZmR0 XG4iKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKworCQlyZXQgPSBnZXRfY3Jhc2hfa2VybmVsX2xv YWRfcmFuZ2UoJnN0YXJ0LCAmZW5kKTsKKwkJaWYgKHJldCkgeworCQkJZnByaW50ZihzdGRlcnIs ICJDb3VsZG4ndCBnZXQgY3Jhc2hrZW5lbCByZWdpb25cbiIpOworCQkJcmV0dXJuIHJldDsKKwkJ fQorCisJCXJldCA9IGR0Yl9hZGRfcmFuZ2VfcHJvcGVydHkoJmZkdC0+YnVmLCAmZmR0LT5zaXpl LCBzdGFydCwgZW5kLAorCQkJCQkgICAgICJjaG9zZW4iLCAibGludXgsdXNhYmxlLW1lbW9yeS1y YW5nZSIpOworCQlpZiAocmV0KSB7CisJCQlmcHJpbnRmKHN0ZGVyciwgIkNvdWxkbid0IGFkZCB1 c2FibGUtbWVtb3J5LXJhbmdlIHRvIGZkdFxuIik7CisJCQlyZXR1cm4gcmV0OworCQl9CisKKwkJ bWF4X3VzYWJsZSA9IGVuZDsKKwl9IGVsc2UgeworCQkvKgorCQkgKiBNYWtlIHN1cmUgd2UgcmVt b3ZlIGVsZmNvcmVoZHIgYW5kIHVzYWJsZS1tZW1vcnktcmFuZ2UKKwkJICogd2hlbiBzd2l0Y2hp bmcgZnJvbSBjcmFzaCBrZXJuZWwgdG8gYSBub3JtYWwgb25lLgorCQkgKi8KKwkJZHRiX2RlbGV0 ZV9wcm9wZXJ0eShmZHQtPmJ1ZiwgImNob3NlbiIsICJsaW51eCxlbGZjb3JlaGRyIik7CisJCWR0 Yl9kZWxldGVfcHJvcGVydHkoZmR0LT5idWYsICJjaG9zZW4iLCAibGludXgsdXNhYmxlLW1lbW9y eS1yYW5nZSIpOworCX0KKworCS8qIERvIHdlIG5lZWQgdG8gaW5jbHVkZSBhbiBpbml0cmQgaW1h Z2UgPyAqLworCWlmICghYXJjaF9vcHRpb25zLmluaXRyZF9wYXRoICYmICFhcmNoX29wdGlvbnMu aW5pdHJkX2VuZCkKKwkJZHRiX2NsZWFyX2luaXRyZCgmZmR0LT5idWYsICZmZHQtPnNpemUpOwor CWVsc2UgaWYgKGFyY2hfb3B0aW9ucy5pbml0cmRfcGF0aCkgeworCQlpZiAoYXJjaF9vcHRpb25z LmluaXRyZF9lbmQpCisJCQlmcHJpbnRmKHN0ZGVyciwgIldhcm5pbmc6IEFuIGluaXRyZCBpbWFn ZSB3YXMgcHJvdmlkZWQiCisJCQkJCSIsIHdpbGwgaWdub3JlIHJldXNlaW5pdHJkXG4iKTsKKwor CQlpbml0cmRfYnVmID0gc2x1cnBfZmlsZShhcmNoX29wdGlvbnMuaW5pdHJkX3BhdGgsCisJCQkJ CSZpbml0cmRfc2l6ZSk7CisJCWlmICghaW5pdHJkX2J1ZikgeworCQkJZnByaW50ZihzdGRlcnIs ICJDb3VsZG4ndCByZWFkIHByb3ZpZGVkIGluaXRyZFxuIik7CisJCQlyZXR1cm4gLUVJTlZBTDsK KwkJfQorCisJCWluaXRyZF9iYXNlID0gYWRkX2J1ZmZlcl9waHlzX3ZpcnQoaW5mbywgaW5pdHJk X2J1ZiwKKwkJCQkJCSAgIGluaXRyZF9zaXplLAorCQkJCQkJICAgaW5pdHJkX3NpemUsIDAsCisJ CQkJCQkgICBtaW5fdXNhYmxlLAorCQkJCQkJICAgbWF4X3VzYWJsZSwgLTEsIDApOworCisJCWR0 Yl9zZXRfaW5pdHJkKCZmZHQtPmJ1ZiwgJmZkdC0+c2l6ZSwgaW5pdHJkX2Jhc2UsCisJCQkgICAg ICAgaW5pdHJkX2Jhc2UgKyBpbml0cmRfc2l6ZSk7CisKKwkJZGJncHJpbnRmKCJCYXNlIGFkZHIg Zm9yIGluaXRyZCBpbWFnZTogMHglbFhcbiIsIGluaXRyZF9iYXNlKTsKKwkJbWF4X3VzYWJsZSA9 IGluaXRyZF9iYXNlOworCX0KKworCS8qIEFkZCBkZXZpY2UgdHJlZSAqLworCWFkZF9idWZmZXJf cGh5c192aXJ0KGluZm8sIGZkdC0+YnVmLCBmZHQtPnNpemUsIGZkdC0+c2l6ZSwgMCwKKwkJCSAg ICAgbWluX3VzYWJsZSwgbWF4X3VzYWJsZSwgLTEsIDApOworCisJcmV0dXJuIDA7Cit9CisKKwor LyoqKioqKioqKioqKioqXAorKiBFTlRSWSBQT0lOVFMgKgorXCoqKioqKioqKioqKioqLworCit2 b2lkIGFyY2hfdXNhZ2Uodm9pZCkKK3sKKwlwcmludGYocmlzY3Zfb3B0c191c2FnZSk7Cit9CisK K2ludCBhcmNoX3Byb2Nlc3Nfb3B0aW9ucyhpbnQgYXJnYywgY2hhciAqKmFyZ3YpCit7CisJc3Rh dGljIGNvbnN0IHN0cnVjdCBvcHRpb24gb3B0aW9uc1tdID0geworCQlLRVhFQ19BUkNIX09QVElP TlMKKwkJeyAwIH0sCisJfTsKKwlzdGF0aWMgY29uc3QgY2hhciBzaG9ydF9vcHRpb25zW10gPSBL RVhFQ19BUkNIX09QVF9TVFI7CisJc3RydWN0IHN0YXQgc3QgPSB7MH07CisJY2hhciAqYXBwZW5k ID0gTlVMTDsKKwljaGFyICpjbWRsaW5lID0gTlVMTDsKKwl2b2lkICp0bXAgPSBOVUxMOworCW9m Zl90IHRtcF9zaXplID0gMDsKKwlpbnQgb3B0ID0gMDsKKwlpbnQgcmV0ID0gMDsKKworCXdoaWxl ICgob3B0ID0gZ2V0b3B0X2xvbmcoYXJnYywgYXJndiwgc2hvcnRfb3B0aW9ucywKKwkJCQkgIG9w dGlvbnMsIDApKSAhPSAtMSkgeworCQlzd2l0Y2ggKG9wdCkgeworCQljYXNlIE9QVF9BUFBFTkQ6 CisJCQlhcHBlbmQgPSBvcHRhcmc7CisJCQlicmVhazsKKwkJY2FzZSBPUFRfQ01ETElORToKKwkJ CWlmIChjbWRsaW5lKQorCQkJCWZwcmludGYoc3RkZXJyLAorCQkJCQkiV2FybmluZzogS2VybmVs J3MgY21kbGluZSAiCisJCQkJCSJzZXQgdHdpY2UgIVxuIik7CisJCQljbWRsaW5lID0gb3B0YXJn OworCQkJYnJlYWs7CisJCWNhc2UgT1BUX1JFVVNFX0NNRExJTkU6CisJCQlpZiAoY21kbGluZSkK KwkJCQlmcHJpbnRmKHN0ZGVyciwKKwkJCQkJIldhcm5pbmc6IEtlcm5lbCdzIGNtZGxpbmUgIgor CQkJCQkic2V0IHR3aWNlICFcbiIpOworCQkJY21kbGluZSA9IGdldF9jb21tYW5kX2xpbmUoKTsK KwkJCWJyZWFrOworCQljYXNlIE9QVF9EVEI6CisJCQlyZXQgPSBzdGF0KG9wdGFyZywgJnN0KTsK KwkJCWlmIChyZXQpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwKKwkJCQkJIkNvdWxkIG5vdCBmaW5k IHRoZSBwcm92aWRlZCBkdGIgIVxuIik7CisJCQkJcmV0dXJuIC1FSU5WQUw7CisJCQl9CisJCQlh cmNoX29wdGlvbnMuZmR0X3BhdGggPSBvcHRhcmc7CisJCQlicmVhazsKKwkJY2FzZSBPUFRfSU5J VFJEOgorCQkJcmV0ID0gc3RhdChvcHRhcmcsICZzdCk7CisJCQlpZiAocmV0KSB7CisJCQkJZnBy aW50ZihzdGRlcnIsCisJCQkJCSJDb3VsZCBub3QgZmluZCB0aGUgcHJvdmlkZWQgIgorCQkJCQki aW5pdHJkIGltYWdlICFcbiIpOworCQkJCXJldHVybiAtRUlOVkFMOworCQkJfQorCQkJYXJjaF9v cHRpb25zLmluaXRyZF9wYXRoID0gb3B0YXJnOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQli cmVhazsKKwkJfQorCX0KKworCS8qIEhhbmRsZSBLZXJuZWwncyBjb21tYW5kIGxpbmUgKi8KKwlp ZiAoYXBwZW5kICYmICFjbWRsaW5lKQorCQlmcHJpbnRmKHN0ZGVyciwgIldhcm5pbmc6IE5vIGNt ZGxpbmUgcHJvdmlkZWQsICIKKwkJCQkidXNpbmcgYXBwZW5kIHN0cmluZyBhcyBjbWRsaW5lXG4i KTsKKwlpZiAoIWFwcGVuZCAmJiAhY21kbGluZSkKKwkJZnByaW50ZihzdGRlcnIsICJXYXJuaW5n OiBObyBjbWRsaW5lIG9yIGFwcGVuZCBzdHJpbmcgIgorCQkJCSJwcm92aWRlZFxuIik7CisKKwlp ZiAoYXBwZW5kIHx8IGNtZGxpbmUpCisJCS8qCisJCSAqIE5vdGUgdGhhdCB0aGlzIGFsc28gaGFu ZGxlcyB0aGUgY2FzZSB3aGVyZSAiY21kbGluZSIKKwkJICogb3IgImFwcGVuZCIgaXMgTlVMTC4K KwkJICovCisJCWFyY2hfb3B0aW9ucy5jbWRsaW5lID0gY29uY2F0X2NtZGxpbmUoY21kbGluZSwg YXBwZW5kKTsKKworCS8qIEhhbmRsZSBGRFQgaW1hZ2UgKi8KKwlpZiAoIWFyY2hfb3B0aW9ucy5m ZHRfcGF0aCkgeworCQlyZXQgPSBzdGF0KCIvc3lzL2Zpcm13YXJlL2ZkdCIsICZzdCk7CisJCWlm IChyZXQpIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiTm8gZHRiIHByb3ZpZGVkIGFuZCAiCisJCQkJ CSIvc3lzL2Zpcm13YXJlL2ZkdCBpcyBub3QgcHJlc2VudFxuIik7CisJCQlyZXR1cm4gLUVJTlZB TDsKKwkJfQorCQlmcHJpbnRmKHN0ZGVyciwgIldhcm5pbmc6IE5vIGR0YiBwcm92aWRlZCwgIgor CQkJCSJ1c2luZyAvc3lzL2Zpcm13YXJlL2ZkdFxuIik7CisJCWFyY2hfb3B0aW9ucy5mZHRfcGF0 aCA9ICIvc3lzL2Zpcm13YXJlL2ZkdCI7CisJfQorCisJdG1wID0gc2x1cnBfZmlsZShhcmNoX29w dGlvbnMuZmR0X3BhdGgsICZ0bXBfc2l6ZSk7CisJaWYgKCF0bXApIHsKKwkJZnByaW50ZihzdGRl cnIsICJDb3VsZG4ndCByZWFkIHByb3ZpZGVkIGZkdFxuIik7CisJCXJldHVybiAtRUlOVkFMOwor CX0KKworCXJldCA9IGZkdF9jaGVja19oZWFkZXIodG1wKTsKKwlpZiAocmV0KSB7CisJCWZwcmlu dGYoc3RkZXJyLCAiR290IGFuIGl2YWxpZCBmZHQgaW1hZ2UgIVxuIik7CisJCWZyZWUodG1wKTsK KwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCXByb3ZpZGVkX2ZkdC5idWYgPSB0bXA7CisJcHJvdmlk ZWRfZmR0LnNpemUgPSB0bXBfc2l6ZTsKKworCWlmIChhcmNoX29wdGlvbnMuY21kbGluZSkgewor CQlyZXQgPSBkdGJfc2V0X2Jvb3RhcmdzKCZwcm92aWRlZF9mZHQuYnVmLCAmcHJvdmlkZWRfZmR0 LnNpemUsCisJCQkJICAgICAgIGFyY2hfb3B0aW9ucy5jbWRsaW5lKTsKKwkJaWYgKHJldCA8IDAp IHsKKwkJCWZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IHNldCBib290YXJncyBvbiAiCisJCQkJ CSJ0aGUgZmR0IGltYWdlXG4iKTsKKwkJCXJldHVybiByZXQ7CisJCX0KKwl9CisKKwlhcmNoX29w dGlvbnMuZmR0ID0gJnByb3ZpZGVkX2ZkdDsKKworCXJldHVybiAwOworfQorCisvKgorICogVGhp cyBvbmUgaXMgY2FsbGVkIGFmdGVyIGFyY2hfcHJvY2Vzc19vcHRpb25zIHNvIHdlIGFscmVhZHkK KyAqIGhhdmUgYW4gZmR0IGltYWdlIGluIHBsYWNlLgorICovCit2b2lkIGFyY2hfcmV1c2VfaW5p dHJkKHZvaWQpCit7CisJY29uc3QgdWludDMyX3QgKnByb3AzMiA9IE5VTEw7CisJdWludDMyX3Qg YWRkcl9jZWxscyA9IDA7CisJY29uc3Qgdm9pZCAqcHJvcCA9IDA7CisJaW50IHByb3Bfc2l6ZSA9 IDA7CisJdWludDY0X3QgaW5pdHJkX3N0YXJ0ID0gMDsKKwl1aW50NjRfdCBpbml0cmRfZW5kID0g MDsKKwlpbnQgY2hvc2VuX29mZnNldCA9IDA7CisJc3RydWN0IGZkdF9pbWFnZSAqZmR0ID0gJnBy b3ZpZGVkX2ZkdDsKKworCWNob3Nlbl9vZmZzZXQgPSBmZHRfc3Vibm9kZV9vZmZzZXQoZmR0LT5i dWYsIDAsICJjaG9zZW4iKTsKKwlpZiAoY2hvc2VuX29mZnNldCA8IDApIHsKKwkJZnByaW50Zihz dGRlcnIsICJObyAvY2hvc2VuIG5vZGUgZm91bmQgb24gZmR0IGltYWdlICIKKwkJCQkidW5hYmxl IHRvIHJldXNlIGluaXRyZFxuIik7CisJCXJldHVybjsKKwl9CisKKwlwcm9wMzIgPSBmZHRfZ2V0 cHJvcChmZHQtPmJ1ZiwgMCwgIiNhZGRyZXNzLWNlbGxzIiwgTlVMTCk7CisJaWYgKCFwcm9wMzIp IHsKKwkJZnByaW50ZihzdGRlcnIsICJObyAjYWRkcmVzcy1jZWxscyBwcm9wZXJ0eSBvbiByb290 IG5vZGVcbiIpOworCQlyZXR1cm47CisJfQorCWFkZHJfY2VsbHMgPSBiZTMyX3RvX2NwdSgqcHJv cDMyKTsKKworCXByb3AgPSBmZHRfZ2V0cHJvcChmZHQtPmJ1ZiwgY2hvc2VuX29mZnNldCwKKwkJ CSAgICJsaW51eCxpbml0cmQtc3RhcnQiLCAmcHJvcF9zaXplKTsKKwlpZiAoIXByb3ApIHsKKwkJ ZnByaW50ZihzdGRlcnIsICJDb3VsZCBub3QgZ2V0IGxpbnV4LGluaXRyZC1zdGFydFxuIik7CisJ CXJldHVybjsKKwl9CisJZHRiX2V4dHJhY3RfaW50X3Byb3BlcnR5KCZpbml0cmRfc3RhcnQsIHBy b3AsIGFkZHJfY2VsbHMpOworCisJcHJvcCA9IGZkdF9nZXRwcm9wKGZkdC0+YnVmLCBjaG9zZW5f b2Zmc2V0LAorCQkJICAgImxpbnV4LGluaXRyZC1lbmQiLCAmcHJvcF9zaXplKTsKKwlpZiAoIXBy b3ApIHsKKwkJZnByaW50ZihzdGRlcnIsICJDb3VsZCBub3QgZ2V0IGxpbnV4LGluaXRyZC1lbmRc biIpOworCQlyZXR1cm47CisJfQorCWR0Yl9leHRyYWN0X2ludF9wcm9wZXJ0eSgmaW5pdHJkX2Vu ZCwgcHJvcCwgYWRkcl9jZWxscyk7CisKKwlhcmNoX29wdGlvbnMuaW5pdHJkX3N0YXJ0ID0gaW5p dHJkX3N0YXJ0OworCWFyY2hfb3B0aW9ucy5pbml0cmRfZW5kID0gaW5pdHJkX2VuZDsKKwlkYmdw cmludGYoImluaXRyZF9zdGFydDogMHglbFgsIGluaXRyZF9lbmQ6IDB4JWxYXG4iLAorCQkgIGlu aXRyZF9zdGFydCwgaW5pdHJkX2VuZCk7CisKK30KKworc3RhdGljIGJvb2wgdG9fYmVfZXhjbHVk ZWQoY2hhciAqc3RyLCB1bnNpZ25lZCBsb25nIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgbG9u ZyBlbmQpCit7CisJaWYgKCFzdHJuY21wKHN0ciwgQ1JBU0hfS0VSTkVMLCBzdHJsZW4oQ1JBU0hf S0VSTkVMKSkpIHsKKwkJdWludDY0X3QgbG9hZF9zdGFydCwgbG9hZF9lbmQ7CisKKwkJaWYgKCFn ZXRfY3Jhc2hfa2VybmVsX2xvYWRfcmFuZ2UoJmxvYWRfc3RhcnQsICZsb2FkX2VuZCkgJiYKKwkJ ICAgIChsb2FkX3N0YXJ0ID09IHN0YXJ0KSAmJiAobG9hZF9lbmQgPT0gZW5kKSkKKwkJCXJldHVy biBmYWxzZTsKKworCQlyZXR1cm4gdHJ1ZTsKKwl9CisKKwlpZiAoIXN0cm5jbXAoc3RyLCBTWVNU RU1fUkFNLCBzdHJsZW4oU1lTVEVNX1JBTSkpIHx8CisJICAgICFzdHJuY21wKHN0ciwgS0VSTkVM X0NPREUsIHN0cmxlbihLRVJORUxfQ09ERSkpIHx8CisJICAgICFzdHJuY21wKHN0ciwgS0VSTkVM X0RBVEEsIHN0cmxlbihLRVJORUxfREFUQSkpKQorCQlyZXR1cm4gZmFsc2U7CisJZWxzZQorCQly ZXR1cm4gdHJ1ZTsKK30KKworaW50IGdldF9tZW1vcnlfcmFuZ2VzKHN0cnVjdCBtZW1vcnlfcmFu Z2UgKipyYW5nZSwgaW50ICpudW1fcmFuZ2VzLAorCQkgICAgICB1bnNpZ25lZCBsb25nIGtleGVj X2ZsYWdzKQoreworCXN0cnVjdCBtZW1vcnlfcmFuZ2VzIHN5c21lbV9yYW5nZXMgPSB7MH07CisJ Y29uc3QgY2hhciAqaW9tZW0gPSBwcm9jX2lvbWVtKCk7CisJc3RydWN0IG1lbW9yeV9yYW5nZSBl eGNsX3JhbmdlOworCXVuc2lnbmVkIGxvbmcgbG9uZyBzdGFydCwgZW5kOworCWludCBjb25zdW1l ZCwgY291bnQsIHJldCA9IDA7CisJRklMRSAqZnAgPSBOVUxMLCAqc3AgPSBOVUxMOworCWNoYXIg bGluZVtNQVhfTElORV0sICpzdHI7CisKKwlmcCA9IGZvcGVuKGlvbWVtLCAiciIpOworCWlmICgh ZnApIHsKKwkJZnByaW50ZihzdGRlcnIsICJDYW5ub3Qgb3BlbiAlczogJXNcbiIsIGlvbWVtLCBz dHJlcnJvcihlcnJubykpOworCQlyZXR1cm4gLTE7CisJfQorCisJc3AgPSBmb3Blbihpb21lbSwg InIiKTsKKwlpZiAoIXNwKSB7CisJCWZwcmludGYoc3RkZXJyLCAiQ2Fubm90IG9wZW4gJXM6ICVz XG4iLCBpb21lbSwgc3RyZXJyb3IoZXJybm8pKTsKKwkJcmV0ID0gLTE7CisJCWdvdG8gZXJyOwor CX0KKworCS8qCisJICogUGVyZm9ybSB0d28gcGFzc2VzOiBGaXJzdCBhZGQgYWxsIFN5c3RlbSBS QU0sIGFuZCB0aGVuCisJICogZXhjbHVkZSB0aGUgIlJlc2VydmVkIiByYW5nZXMiCisJICovCisJ d2hpbGUgKGZnZXRzKGxpbmUsIHNpemVvZihsaW5lKSwgZnApICE9IDApIHsKKwkJY291bnQgPSBz c2NhbmYobGluZSwgIiVsbHgtJWxseCA6ICVuIiwgJnN0YXJ0LCAmZW5kLCAmY29uc3VtZWQpOwor CQlpZiAoY291bnQgIT0gMikKKwkJCWNvbnRpbnVlOworCQlzdHIgPSBsaW5lICsgY29uc3VtZWQ7 CisKKwkJaWYgKCFzdHJuY21wKHN0ciwgU1lTVEVNX1JBTSwgc3RybGVuKFNZU1RFTV9SQU0pKSkg eworCQkJcmV0ID0gbWVtX3JlZ2lvbnNfYWxsb2NfYW5kX2FkZCgmc3lzbWVtX3JhbmdlcywKKwkJ CQkJc3RhcnQsIGVuZCAtIHN0YXJ0ICsgMSwgUkFOR0VfUkFNKTsKKwkJCWlmIChyZXQpIHsKKwkJ CQlmcHJpbnRmKHN0ZGVyciwKKwkJCQkJIkNhbm5vdCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHJhbmdl c1xuIik7CisJCQkJcmV0ID0gLUVOT01FTTsKKwkJCQlnb3RvIGVycjsKKwkJCX0KKworCQl9CisJ fQorCisJd2hpbGUgKGZnZXRzKGxpbmUsIHNpemVvZihsaW5lKSwgc3ApICE9IDApIHsKKwkJY291 bnQgPSBzc2NhbmYobGluZSwgIiVsbHgtJWxseCA6ICVuIiwgJnN0YXJ0LCAmZW5kLCAmY29uc3Vt ZWQpOworCQlpZiAoY291bnQgIT0gMikKKwkJCWNvbnRpbnVlOworCQlzdHIgPSBsaW5lICsgY29u c3VtZWQ7CisKKwkJaWYgKHRvX2JlX2V4Y2x1ZGVkKHN0ciwgc3RhcnQsIGVuZCkpIHsKKwkJCWV4 Y2xfcmFuZ2Uuc3RhcnQgPSBzdGFydDsKKwkJCWV4Y2xfcmFuZ2UuZW5kID0gZW5kOworCisJCQly ZXQgPSBtZW1fcmVnaW9uc19hbGxvY19hbmRfZXhjbHVkZSgmc3lzbWVtX3JhbmdlcywgJmV4Y2xf cmFuZ2UpOworCQkJaWYgKHJldCkgeworCQkJCWZwcmludGYoc3RkZXJyLAorCQkJCQkiQ2Fubm90 IGFsbG9jYXRlIG1lbW9yeSBmb3IgcmFuZ2VzIChleGNsdWRlKVxuIik7CisJCQkJcmV0ID0gLUVO T01FTTsKKwkJCQlnb3RvIGVycjsKKwkJCX0KKwkJfQorCX0KKworCSpyYW5nZSA9IHN5c21lbV9y YW5nZXMucmFuZ2VzOworCSpudW1fcmFuZ2VzID0gc3lzbWVtX3Jhbmdlcy5zaXplOworCisJZGJn cHJpbnRfbWVtX3JhbmdlKCJTeXN0ZW0gUkFNIHJhbmdlczsiLAorCQkJCXN5c21lbV9yYW5nZXMu cmFuZ2VzLCBzeXNtZW1fcmFuZ2VzLnNpemUpOworCisJcmV0ID0gMDsKKyBlcnI6CisJaWYgKGZw KQorCQlmY2xvc2UoZnApOworCWlmIChzcCkKKwkJZmNsb3NlKHNwKTsKKwlyZXR1cm4gcmV0Owor fQorCisvKioqKioqKlwKKyogU1RVQlMgKgorXCoqKioqKiovCisKK2ludCBhcmNoX2NvbXBhdF90 cmFtcG9saW5lKHN0cnVjdCBrZXhlY19pbmZvICpVTlVTRUQoaW5mbykpCit7CisJcmV0dXJuIDA7 Cit9CisKK3ZvaWQgYXJjaF91cGRhdGVfcHVyZ2F0b3J5KHN0cnVjdCBrZXhlY19pbmZvICpVTlVT RUQoaW5mbykpCit7Cit9CisKK2ludCBhcmNoX2RvX2V4Y2x1ZGVfc2VnbWVudChzdHJ1Y3Qga2V4 ZWNfaW5mbyAqVU5VU0VEKGluZm8pLCBzdHJ1Y3Qga2V4ZWNfc2VnbWVudCAqVU5VU0VEKHNlZ21l bnQpKQoreworCXJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEva2V4ZWMvYXJjaC9yaXNjdi9rZXhl Yy1yaXNjdi5oIGIva2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5oCm5ldyBmaWxlIG1vZGUg MTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uYzQzMjNhNjVkYWNmCi0tLSAvZGV2L251bGwKKysr IGIva2V4ZWMvYXJjaC9yaXNjdi9rZXhlYy1yaXNjdi5oCkBAIC0wLDAgKzEsMzIgQEAKKy8qIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wICovCisvKgorICogQ29weXJpZ2h0IChDKSAy MDE5IEZPUlRILUlDUy9DQVJWCisgKiAgICAgICAgICAgICAgTmljayBLb3NzaWZpZGlzIDxtaWNr QGljcy5mb3J0aC5ncj4KKyAqLworCitzdHJ1Y3QgZmR0X2ltYWdlIHsKKwljaGFyCSpidWY7CisJ b2ZmX3QJc2l6ZTsKK307CisKK3N0cnVjdCByaXNjdl9vcHRzIHsKKwljaGFyICpjbWRsaW5lOwor CWNoYXIgKmZkdF9wYXRoOworCWNoYXIgKmluaXRyZF9wYXRoOworCXVpbnQ2NF90IGluaXRyZF9z dGFydDsKKwl1aW50NjRfdCBpbml0cmRfZW5kOworCXN0cnVjdCBmZHRfaW1hZ2UgKmZkdDsKK307 CisKKy8qIGNyYXNoZHVtcC1yaXNjdi5jICovCitleHRlcm4gc3RydWN0IG1lbW9yeV9yYW5nZSBl bGZjb3JlaGRyX21lbTsKK2ludCBsb2FkX2VsZmNvcmVoZHIoc3RydWN0IGtleGVjX2luZm8gKmlu Zm8pOworCisvKiBrZXhlYy1yaXNjdi5jICovCitpbnQgbG9hZF9leHRyYV9zZWdtZW50cyhzdHJ1 Y3Qga2V4ZWNfaW5mbyAqaW5mbywgdWludDY0X3Qga2VybmVsX2Jhc2UsCisJCQl1aW50NjRfdCBr ZXJuZWxfc2l6ZSwgdWludDY0X3QgbWF4X2FkZHIpOworCitpbnQgZWxmX3Jpc2N2X3Byb2JlKGNv bnN0IGNoYXIgKmJ1Ziwgb2ZmX3QgbGVuKTsKK3ZvaWQgZWxmX3Jpc2N2X3VzYWdlKHZvaWQpOwor aW50IGVsZl9yaXNjdl9sb2FkKGludCBhcmdjLCBjaGFyICoqYXJndiwgY29uc3QgY2hhciAqYnVm LCBvZmZfdCBsZW4sCisJCSAgIHN0cnVjdCBrZXhlY19pbmZvICppbmZvKTsKZGlmZiAtLWdpdCBh L2tleGVjL2R0LW9wcy5jIGIva2V4ZWMvZHQtb3BzLmMKaW5kZXggMGE5NmI3NWY2NWFhLi4zZTI4 NWFiMjA0M2IgMTAwNjQ0Ci0tLSBhL2tleGVjL2R0LW9wcy5jCisrKyBiL2tleGVjL2R0LW9wcy5j CkBAIC00LDkgKzQsMTEgQEAKICNpbmNsdWRlIDxsaWJmZHQuaD4KICNpbmNsdWRlIDxzdGRpby5o PgogI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHN0ZGJvb2wuaD4KIAogI2luY2x1ZGUg ImtleGVjLmgiCiAjaW5jbHVkZSAiZHQtb3BzLmgiCisjaW5jbHVkZSAibWVtX3JlZ2lvbnMuaCIK IAogc3RhdGljIGNvbnN0IGNoYXIgbl9jaG9zZW5bXSA9ICJjaG9zZW4iOwogCkBAIC05NSw3ICs5 Nyw3IEBAIGludCBkdGJfc2V0X3Byb3BlcnR5KGNoYXIgKipkdGIsIG9mZl90ICpkdGJfc2l6ZSwg Y29uc3QgY2hhciAqbm9kZSwKIAogCXN0cmNweShuZXdfbm9kZSwgIi8iKTsKIAlzdHJjYXQobmV3 X25vZGUsIG5vZGUpOwotCQorCiAJbm9kZW9mZnNldCA9IGZkdF9wYXRoX29mZnNldChuZXdfZHRi LCBuZXdfbm9kZSk7CiAKIAlpZiAobm9kZW9mZnNldCA9PSAtRkRUX0VSUl9OT1RGT1VORCkgewpA QCAtMTc0LDMgKzE3Niw0NDEgQEAgaW50IGR0Yl9kZWxldGVfcHJvcGVydHkoY2hhciAqZHRiLCBj b25zdCBjaGFyICpub2RlLCBjb25zdCBjaGFyICpwcm9wKQogCWZyZWUobmV3X25vZGUpOwogCXJl dHVybiByZXN1bHQ7CiB9CisKK3N0YXRpYyBpbnQgZHRiX2dldF9udW1fY2VsbHMoY2hhciAqZHRi LCBpbnQgbm9kZW9mZnNldCwgdWludDMyX3QgKmFkZHJfY2VsbHMsCisJCQkgICAgIHVpbnQzMl90 ICpzaXplX2NlbGxzLCBib29sIHJlY3Vyc2l2ZSkKK3sKKwljb25zdCB1aW50MzJfdCAqcHJvcDMy ID0gTlVMTDsKKwlpbnQgY3Vycl9vZmZzZXQgPSBub2Rlb2Zmc2V0OworCWludCBwcm9wX2xlbiA9 IDA7CisJKmFkZHJfY2VsbHMgPSAwOworCSpzaXplX2NlbGxzID0gMDsKKworCWRvIHsKKwkJcHJv cDMyID0gZmR0X2dldHByb3AoZHRiLCBjdXJyX29mZnNldCwgIiNhZGRyZXNzLWNlbGxzIiwgJnBy b3BfbGVuKTsKKwkJY3Vycl9vZmZzZXQgPSBmZHRfcGFyZW50X29mZnNldChkdGIsIGN1cnJfb2Zm c2V0KTsKKwl9IHdoaWxlICghcHJvcDMyICYmIHByb3BfbGVuID09IC1GRFRfRVJSX05PVEZPVU5E ICYmIHJlY3Vyc2l2ZSk7CisKKwlpZiAoIXByb3AzMikgeworCQlkYmdwcmludGYoIkNvdWxkIG5v dCBnZXQgI2FkZHJlc3MtY2VsbHMgcHJvcGVydHkgZm9yICVzICglcylcbiIsCisJCQkgIGZkdF9n ZXRfbmFtZShkdGIsIG5vZGVvZmZzZXQsIE5VTEwpLCBmZHRfc3RyZXJyb3Iobm9kZW9mZnNldCkp OworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisJKmFkZHJfY2VsbHMgPSBmZHQzMl90b19jcHUoKnBy b3AzMik7CisKKwljdXJyX29mZnNldCA9IG5vZGVvZmZzZXQ7CisJZG8geworCQlwcm9wMzIgPSBm ZHRfZ2V0cHJvcChkdGIsIGN1cnJfb2Zmc2V0LCAiI3NpemUtY2VsbHMiLCAmcHJvcF9sZW4pOwor CQljdXJyX29mZnNldCA9IGZkdF9wYXJlbnRfb2Zmc2V0KGR0YiwgY3Vycl9vZmZzZXQpOworCX0g d2hpbGUgKCFwcm9wMzIgJiYgcHJvcF9sZW4gPT0gLUZEVF9FUlJfTk9URk9VTkQgJiYgcmVjdXJz aXZlKTsKKworCWlmICghcHJvcDMyKSB7CisJCWRiZ3ByaW50ZigiQ291bGQgbm90IGdldCAjc2l6 ZS1jZWxscyBwcm9wZXJ0eSBmb3IgJXMgKCVzKVxuIiwKKwkJCSAgZmR0X2dldF9uYW1lKGR0Yiwg bm9kZW9mZnNldCwgTlVMTCksIGZkdF9zdHJlcnJvcihub2Rlb2Zmc2V0KSk7CisJCXJldHVybiAt RUlOVkFMOworCX0KKwkqc2l6ZV9jZWxscyA9IGZkdDMyX3RvX2NwdSgqcHJvcDMyKTsKKworCWRi Z3ByaW50ZigiJXM6ICNhZGRyZXNzLWNlbGxzOiVkICNzaXplLWNlbGxzOiVkXG4iLAorCQkgZmR0 X2dldF9uYW1lKGR0Yiwgbm9kZW9mZnNldCwgTlVMTCksICphZGRyX2NlbGxzLCAqc2l6ZV9jZWxs cyk7CisKKwlyZXR1cm4gMDsKK30KKwordm9pZCBkdGJfZXh0cmFjdF9pbnRfcHJvcGVydHkodWlu dDY0X3QgKnZhbCwgY29uc3Qgdm9pZCAqYnVmLCB1aW50MzJfdCBjZWxscykKK3sKKwljb25zdCB1 aW50MzJfdCAqcHJvcDMyID0gTlVMTDsKKwljb25zdCB1aW50NjRfdCAqcHJvcDY0ID0gTlVMTDsK KworCWlmIChjZWxscyA9PSAxKSB7CisJCXByb3AzMiA9IChjb25zdCB1aW50MzJfdCAqKSBidWY7 CisJCSp2YWwgPSAodWludDY0X3QpIGJlMzJfdG9fY3B1KCpwcm9wMzIpOworCX0gZWxzZSB7CisJ CS8qIFNraXAgYW55IGxlYWRpbmcgY2VsbHMgKi8KKwkJcHJvcDY0ID0gKGNvbnN0IHVpbnQ2NF90 ICopICh1aW50MzJfdCAqKWJ1ZiArIGNlbGxzIC0gMjsKKwkJKnZhbCA9ICh1aW50NjRfdCkgYmU2 NF90b19jcHUoKnByb3A2NCk7CisJfQorfQorCit2b2lkIGR0Yl9maWxsX2ludF9wcm9wZXJ0eSh2 b2lkICpidWYsIHVpbnQ2NF90IHZhbCwgdWludDMyX3QgY2VsbHMpCit7CisJdWludDMyX3QgcHJv cDMyID0gMDsKKwl1aW50NjRfdCBwcm9wNjQgPSAwOworCisJaWYgKGNlbGxzID09IDEpIHsKKwkJ cHJvcDMyID0gY3B1X3RvX2ZkdDMyKCh1aW50MzJfdCkgdmFsKTsKKwkJbWVtY3B5KGJ1ZiwgJnBy b3AzMiwgc2l6ZW9mKHVpbnQzMl90KSk7CisJfSBlbHNlIHsKKwkJcHJvcDY0ID0gY3B1X3RvX2Zk dDY0KHZhbCk7CisJCS8qIFNraXAgYW55IGxlYWRpbmcgY2VsbHMgKi8KKwkJbWVtY3B5KCh1aW50 NjRfdCAqKSh1aW50MzJfdCAqKWJ1ZiArIGNlbGxzIC0gMiwKKwkJICAgICAgICZwcm9wNjQsIHNp emVvZih1aW50NjRfdCkpOworCX0KK30KKworaW50IGR0Yl9hZGRfcmFuZ2VfcHJvcGVydHkoY2hh ciAqKmR0Yiwgb2ZmX3QgKmR0Yl9zaXplLCB1aW50NjRfdCBzdGFydCwgdWludDY0X3QgZW5kLAor CQkJICAgY29uc3QgY2hhciAqcGFyZW50LCBjb25zdCBjaGFyICpuYW1lKQoreworCXVpbnQzMl90 IGFkZHJfY2VsbHMgPSAwOworCXVpbnQzMl90IHNpemVfY2VsbHMgPSAwOworCWNoYXIgKm5vZGVw YXRoID0gTlVMTDsKKwl2b2lkICpwcm9wID0gTlVMTDsKKwlpbnQgbm9kZW9mZnNldCA9IDA7CisJ aW50IHByb3Bfc2l6ZSA9IDA7CisJaW50IHJldCA9IDA7CisKKwlub2RlcGF0aCA9IG1hbGxvYyhz dHJsZW4oIi8iKSArIHN0cmxlbihwYXJlbnQpICsgMSk7CisJaWYgKCFub2RlcGF0aCkgeworCQlk YmdwcmludGYoIiVzOiBtYWxsb2MgZmFpbGVkXG4iLCBfX2Z1bmNfXyk7CisJCXJldHVybiAtRU5P TUVNOworCX0KKworCXN0cmNweShub2RlcGF0aCwgIi8iKTsKKwlzdHJjYXQobm9kZXBhdGgsIHBh cmVudCk7CisKKwlub2Rlb2Zmc2V0ID0gZmR0X3BhdGhfb2Zmc2V0KCpkdGIsIG5vZGVwYXRoKTsK KwlpZiAobm9kZW9mZnNldCA8IDApIHsKKwkJZGJncHJpbnRmKCIlczogZmR0X3BhdGhfb2Zmc2V0 KCVzKSBmYWlsZWQ6ICVzXG4iLCBfX2Z1bmNfXywKKwkJCSAgbm9kZXBhdGgsIGZkdF9zdHJlcnJv cihub2Rlb2Zmc2V0KSk7CisJCWZyZWUobm9kZXBhdGgpOworCQlyZXR1cm4gbm9kZW9mZnNldDsK Kwl9CisJZnJlZShub2RlcGF0aCk7CisKKwlyZXQgPSBkdGJfZ2V0X251bV9jZWxscygqZHRiLCBu b2Rlb2Zmc2V0LCAmYWRkcl9jZWxscywgJnNpemVfY2VsbHMsIHRydWUpOworCWlmIChyZXQgPCAw KQorCQlyZXR1cm4gcmV0OworCisJLyogQ2FuIHRoZSByYW5nZSBmaXQgd2l0aCB0aGUgZ2l2ZW4g YWRkcmVzcy9zaXplIGNlbGxzID8gKi8KKwlpZiAoKGFkZHJfY2VsbHMgPT0gMSkgJiYgKHN0YXJ0 ID49ICgxVUxMIDw8IDMyKSkpCisJCXJldHVybiAtRUlOVkFMOworCisJaWYgKChzaXplX2NlbGxz ID09IDEpICYmICgoZW5kIC0gc3RhcnQgKyAxKSA+PSAoMVVMTCA8PCAzMikpKQorCQlyZXR1cm4g LUVJTlZBTDsKKworCXByb3Bfc2l6ZSA9IHNpemVvZih1aW50MzJfdCkgKiAoYWRkcl9jZWxscyAr IHNpemVfY2VsbHMpOworCXByb3AgPSBtYWxsb2MocHJvcF9zaXplKTsKKworCWR0Yl9maWxsX2lu dF9wcm9wZXJ0eShwcm9wLCBzdGFydCwgYWRkcl9jZWxscyk7CisJZHRiX2ZpbGxfaW50X3Byb3Bl cnR5KCh2b2lkICopKCh1aW50MzJfdCAqKXByb3AgKyBhZGRyX2NlbGxzKSwKKwkJCSAgICAgIGVu ZCAtIHN0YXJ0ICsgMSwgc2l6ZV9jZWxscyk7CisKKwkvKiBBZGQgYnkgbm9kZSBwYXRoIG5hbWUg Ki8KKwlyZXR1cm4gZHRiX3NldF9wcm9wZXJ0eShkdGIsIGR0Yl9zaXplLCBwYXJlbnQsIG5hbWUs IHByb3AsIHByb3Bfc2l6ZSk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKipcCisqIE1F TU9SWSBSQU5HRVMgSEFORExJTkcgKgorXCoqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3Rh dGljIGludCBkdGJfYWRkX21lbW9yeV9yYW5nZShzdHJ1Y3QgbWVtb3J5X3JhbmdlcyAqbWVtX3Jh bmdlcywgdWludDY0X3Qgc3RhcnQsCisJCQkJdWludDY0X3QgZW5kLCB1bnNpZ25lZCB0eXBlKQor eworCXN0cnVjdCBtZW1vcnlfcmFuZ2UgdGhpc19yZWdpb24gPSB7MH07CisJc3RydWN0IG1lbW9y eV9yYW5nZSAqcmFuZ2VzID0gbWVtX3Jhbmdlcy0+cmFuZ2VzOworCWludCBpID0gMDsKKwlpbnQg cmV0ID0gMDsKKworCWlmIChzdGFydCA9PSBlbmQpIHsKKwkJZGJncHJpbnRmKCJJZ25vcmluZyBl bXB0eSByZWdpb25cbiIpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwkvKiBDaGVjayBpZiB3 ZSBhcmUgYWRkaW5nIGFuIGV4aXN0aW5nIHJlZ2lvbiAqLworCWZvciAoaSA9IDA7IGkgPCBtZW1f cmFuZ2VzLT5zaXplOyBpKyspIHsKKwkJaWYgKHN0YXJ0ID09IHJhbmdlc1tpXS5zdGFydCAmJiBl bmQgPT0gcmFuZ2VzW2ldLmVuZCkgeworCQkJZGJncHJpbnRmKCJEdXBsaWNhdGU6IDB4JWx4IC0g MHglbHhcbiIsIHN0YXJ0LCBlbmQpOworCisJCQlpZiAodHlwZSA9PSByYW5nZXNbaV0udHlwZSkK KwkJCQlyZXR1cm4gMDsKKwkJCWVsc2UgaWYgKHR5cGUgPT0gUkFOR0VfUkVTRVJWRUQpIHsKKwkJ CQlyYW5nZXNbaV0udHlwZSA9IFJBTkdFX1JFU0VSVkVEOworCQkJCXJldHVybiAwOworCQkJfQor CisJCQlkYmdwcmludGYoIkNvbmZsaWN0aW5nIHR5cGVzIGZvciByZWdpb246IDB4JWx4IC0gMHgl bHhcbiIsCisJCQkJICBzdGFydCwgZW5kKTsKKwkJCXJldHVybiAtRUlOVkFMOworCQl9CisJfQor CisJLyoKKwkgKiBSZXNlcnZlZCByZWdpb25zIG1heSBiZSBwYXJ0IG9mIGFuIGV4aXN0aW5nIC9t ZW1vcnkKKwkgKiByZWdpb24gYW5kIHNob3VsZG4ndCBvdmVybGFwIGFjY29yZGluZyB0byBzcGVj LCBzbworCSAqIHNpbmNlIHdlIGFkZCAvbWVtb3J5IHJlZ2lvbnMgZmlyc3QsIHdlIGNhbiBleGNs dWRlCisJICogcmVzZXJ2ZWQgcmVnaW9ucyBoZXJlIGZyb20gdGhlIGV4aXN0aW5nIC9tZW1vcnkg cmVnaW9ucworCSAqIGluY2x1ZGVkIGluIHJhbmdlc1tdLCBzbyB0aGF0IHdlIGRvbid0IGhhdmUg dGhlIHNhbWUKKwkgKiByZWdpb24gdHdpY2UuCisJICovCisJaWYgKHR5cGUgPT0gUkFOR0VfUkVT RVJWRUQpIHsKKwkJdGhpc19yZWdpb24uc3RhcnQgPSBzdGFydDsKKwkJdGhpc19yZWdpb24uZW5k ID0gZW5kIC0gMTsKKwkJdGhpc19yZWdpb24udHlwZSA9IHR5cGU7CisJCXJldCA9IG1lbV9yZWdp b25zX2V4Y2x1ZGUobWVtX3JhbmdlcywgJnRoaXNfcmVnaW9uKTsKKwkJaWYgKHJldCkKKwkJCXJl dHVybiByZXQ7CisJfQorCisJcmV0ID0gbWVtX3JlZ2lvbnNfYWxsb2NfYW5kX2FkZChtZW1fcmFu Z2VzLCBzdGFydCwKKwkJCQkJZW5kIC0gc3RhcnQsIHR5cGUpOworCisJcmV0dXJuIHJldDsKK30K Kworc3RhdGljIGludCBkdGJfYWRkX21lbW9yeV9yZWdpb24oY2hhciAqZHRiLCBpbnQgbm9kZW9m ZnNldCwKKwkJCQkgc3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMsIGludCB0eXBlKQor eworCXVpbnQzMl90IHJvb3RfYWRkcl9jZWxscyA9IDA7CisJdWludDMyX3Qgcm9vdF9zaXplX2Nl bGxzID0gMDsKKwl1aW50NjRfdCBhZGRyID0gMDsKKwl1aW50NjRfdCBzaXplID0gMDsKKwljb25z dCBjaGFyICpyZWcgPSBOVUxMOworCWludCBwcm9wX3NpemUgPSAwOworCWludCBvZmZzZXQgPSAw OworCWludCBlbnRyeV9zaXplID0gMDsKKwlpbnQgbnVtX2VudHJpZXMgPSAwOworCWludCByZXQg PSAwOworCisJLyoKKwkgKiBHZXQgYWRkcmVzcy1jZWxscyBhbmQgc2l6ZS1jZWxscyBwcm9wZXJ0 aWVzIChhY2NvcmRpbmcgdG8KKwkgKiBiaW5kaW5nIHNwZWMgdGhlc2UgYXJlIHRoZSBzYW1lIGFz IGluIHRoZSByb290IG5vZGUpCisJICovCisJcmV0ID0gZHRiX2dldF9udW1fY2VsbHMoZHRiLCAw LCAmcm9vdF9hZGRyX2NlbGxzLCAmcm9vdF9zaXplX2NlbGxzLCBmYWxzZSk7CisJaWYgKHJldCA8 IDApIHsKKwkJZGJncHJpbnRmKCJObyBhZGRyZXNzL3NpemUgY2VsbHMgb24gcm9vdCBub2RlICFc biIpOworCQlyZXR1cm4gcmV0OworCX0KKworCS8qCisJICogUGFyc2UgdGhlIHJlZyBhcnJheSwg YWNvcmRpbmcgdG8gZGV2aWNlIHRyZWUgc3BlYyBpdCBpbmNsdWRlcworCSAqIGFuIGFyYml0YXJ5 IG51bWJlciBvZiA8YWRkcmVzcz48c2l6ZT4gcGFpcnMKKwkgKi8KKwllbnRyeV9zaXplID0gKHJv b3RfYWRkcl9jZWxscyArIHJvb3Rfc2l6ZV9jZWxscykgKiBzaXplb2YodWludDMyX3QpOworCXJl ZyA9IGZkdF9nZXRwcm9wKGR0Yiwgbm9kZW9mZnNldCwgInJlZyIsICZwcm9wX3NpemUpOworCWlm ICghcmVnKSB7CisJCWRiZ3ByaW50ZigiV2FybmluZzogTWFsZm9ybWVkIG1lbW9yeSByZWdpb24g d2l0aCBubyByZWcgcHJvcGVydHkgKCVzKSAhXG4iLAorCQkJICBmZHRfZ2V0X25hbWUoZHRiLCBu b2Rlb2Zmc2V0LCBOVUxMKSk7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCW51bV9lbnRyaWVz ID0gcHJvcF9zaXplIC8gZW50cnlfc2l6ZTsKKwlkYmdwcmludGYoIkdvdCByZWdpb24gd2l0aCAl aSBlbnRyaWVzOiAlc1xuIiwgbnVtX2VudHJpZXMsCisJCSAgZmR0X2dldF9uYW1lKGR0Yiwgbm9k ZW9mZnNldCwgTlVMTCkpOworCisJZm9yIChudW1fZW50cmllcy0tOyBudW1fZW50cmllcyA+PSAw OyBudW1fZW50cmllcy0tKSB7CisJCW9mZnNldCA9IG51bV9lbnRyaWVzICogZW50cnlfc2l6ZTsK KworCQlkdGJfZXh0cmFjdF9pbnRfcHJvcGVydHkoJmFkZHIsIHJlZyArIG9mZnNldCwKKwkJCQkJ IHJvb3RfYWRkcl9jZWxscyk7CisJCW9mZnNldCArPSByb290X2FkZHJfY2VsbHMgKiBzaXplb2Yo dWludDMyX3QpOworCisJCWR0Yl9leHRyYWN0X2ludF9wcm9wZXJ0eSgmc2l6ZSwgcmVnICsgb2Zm c2V0LAorCQkJCQkgcm9vdF9zaXplX2NlbGxzKTsKKworCQlyZXQgPSBkdGJfYWRkX21lbW9yeV9y YW5nZShtZW1fcmFuZ2VzLCBhZGRyLAorCQkJCQkgICBhZGRyICsgc2l6ZSwgdHlwZSk7CisJCWlm IChyZXQpCisJCQlyZXR1cm4gcmV0OworCX0KKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50 IGR0Yl9wYXJzZV9tZW1vcnlfcmVzZXJ2YXRpb25zX3RhYmxlKGNoYXIgKmR0Yiwgc3RydWN0IG1l bW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMpCit7CisJaW50IHRvdGFsX21lbXJzcnYgPSAwOworCXVp bnQ2NF90IGFkZHIgPSAwOworCXVpbnQ2NF90IHNpemUgPSAwOworCWludCByZXQgPSAwOworCWlu dCBpID0gMDsKKworCXRvdGFsX21lbXJzcnYgPSBmZHRfbnVtX21lbV9yc3YoZHRiKTsKKwlmb3Ig KGkgPSAwOyBpIDwgdG90YWxfbWVtcnNydjsgaSsrKSB7CisJCXJldCA9IGZkdF9nZXRfbWVtX3Jz dihkdGIsIGksICZhZGRyLCAmc2l6ZSk7CisJCWlmIChyZXQpCisJCQljb250aW51ZTsKKwkJcmV0 ID0gZHRiX2FkZF9tZW1vcnlfcmFuZ2UobWVtX3JhbmdlcywgYWRkciwgYWRkciArIHNpemUgLSAx LAorCQkJCQkgICBSQU5HRV9SRVNFUlZFRCk7CisJCWlmIChyZXQpCisJCQlyZXR1cm4gcmV0Owor CX0KKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGR0Yl9nZXRfcmVzZXJ2ZWRfbWVtb3J5 X25vZGUoY2hhciAqZHRiKQoreworCXVpbnQzMl90IHJvb3RfYWRkcl9jZWxscyA9IDA7CisJdWlu dDMyX3Qgcm9vdF9zaXplX2NlbGxzID0gMDsKKwl1aW50MzJfdCBhZGRyX2NlbGxzID0gMDsKKwl1 aW50MzJfdCBzaXplX2NlbGxzID0gMDsKKwlpbnQgcHJvcF9zaXplID0gMDsKKwlpbnQgbm9kZW9m ZnNldCA9IDA7CisJaW50IHJldCA9IDA7CisKKwkvKiBHZXQgYWRkcmVzcyAvIHNpemUgY2VsbHMg ZnJvbSByb290IG5vZGUgKi8KKwlyZXQgPSBkdGJfZ2V0X251bV9jZWxscyhkdGIsIDAsICZyb290 X2FkZHJfY2VsbHMsICZyb290X3NpemVfY2VsbHMsIGZhbHNlKTsKKwlpZiAocmV0IDwgMCkgewor CQlkYmdwcmludGYoIk5vIGFkZHJlc3Mvc2l6ZSBjZWxscyBvbiByb290IG5vZGUgIVxuIik7CisJ CXJldHVybiByZXQ7CisJfQorCisJLyogVGhpcyBjYWxscyBmZHRfbmV4dF9ub2RlIGludGVybmFs eSAqLworCW5vZGVvZmZzZXQgPSBmZHRfc3Vibm9kZV9vZmZzZXQoZHRiLCAwLCAicmVzZXJ2ZWQt bWVtb3J5Iik7CisJaWYgKG5vZGVvZmZzZXQgPT0gLUZEVF9FUlJfTk9URk9VTkQpIHsKKwkJcmV0 dXJuIG5vZGVvZmZzZXQ7CisJfSBlbHNlIGlmIChub2Rlb2Zmc2V0IDwgMCkgeworCQlkYmdwcmlu dGYoIkVycm9yIHdoaWxlIGxvb2tpbmcgZm9yIHJlc2VydmVkLW1lbW9yeTogJXNcbiIsCisJCQlm ZHRfc3RyZXJyb3Iobm9kZW9mZnNldCkpOworCQlyZXR1cm4gbm9kZW9mZnNldDsKKwl9CisKKwkv KiBMb29rIGZvciB0aGUgcmFuZ2VzIHByb3BlcnR5ICovCisJZmR0X2dldHByb3AoZHRiLCBub2Rl b2Zmc2V0LCAicmFuZ2VzIiwgJnByb3Bfc2l6ZSk7CisJaWYgKHByb3Bfc2l6ZSA8IDApIHsKKwkJ ZnByaW50ZihzdGRlcnIsICJNYWxmb3JtZWQgcmVzZXJ2ZWQtbWVtb3J5IG5vZGUgKG5vIHJhbmdl cyBwcm9wZXJ0eSkgIVxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCS8qIFZlcmlmeSBh ZGRyZXNzLWNlbGxzIC8gc2l6ZS1jZWxscyAqLworCXJldCA9IGR0Yl9nZXRfbnVtX2NlbGxzKGR0 Yiwgbm9kZW9mZnNldCwgJmFkZHJfY2VsbHMsICZzaXplX2NlbGxzLCBmYWxzZSk7CisJaWYgKHJl dCA8IDApIHsKKwkJZGJncHJpbnRmKCJObyBhZGRyZXNzL3NpemUgY2VsbHMgcHJvcGVydHkgb24g cmVzZXJ2ZWQtbWVtb3J5IG5vZGVcbiIpOworCQlyZXR1cm4gcmV0OworCX0KKworCWlmIChhZGRy X2NlbGxzICE9IHJvb3RfYWRkcl9jZWxscykgeworCQlmcHJpbnRmKHN0ZGVyciwgIkludmFsaWQg I2FkZHJlc3MtY2VsbHMgcHJvcGVydHkgb24gcmVzZXJ2ZWQtbWVtb3J5IG5vZGVcbiIpOworCQly ZXR1cm4gLUVJTlZBTDsKKwl9CisKKwlpZiAoc2l6ZV9jZWxscyAhPSByb290X3NpemVfY2VsbHMp IHsKKwkJZnByaW50ZihzdGRlcnIsICJJbnZhbGlkICNzaXplLWNlbGxzIHByb3BlcnR5IG9uIHJl c2VydmVkLW1lbW9yeSBub2RlXG4iKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwl9CisKKwlyZXR1 cm4gbm9kZW9mZnNldDsKK30KKworc3RhdGljIGludCBkdGJfcGFyc2VfcmVzZXJ2ZWRfbWVtb3J5 X25vZGUoY2hhciAqZHRiLCBzdHJ1Y3QgbWVtb3J5X3JhbmdlcyAqbWVtX3JhbmdlcykKK3sKKwlp bnQgbm9kZW9mZnNldCA9IDA7CisJaW50IG5vZGVfZGVwdGggPSAwOworCWludCBwYXJlbnRfZGVw dGggPSAwOworCWludCByZXQgPSAwOworCisJbm9kZW9mZnNldCA9IGR0Yl9nZXRfcmVzZXJ2ZWRf bWVtb3J5X25vZGUoZHRiKTsKKwlpZiAobm9kZW9mZnNldCA9PSAtRkRUX0VSUl9OT1RGT1VORCkK KwkJcmV0dXJuIDA7CisJZWxzZSBpZiAobm9kZW9mZnNldCA8IDApCisJCXJldHVybiBub2Rlb2Zm c2V0OworCisJLyogR290IHRoZSBwYXJlbnQgbm9kZSwgY2hlY2sgZm9yIHN1Yi1ub2RlcyAqLwor CisJLyogZmR0X25leHRfbm9kZSgpIGluY3JlYXNlcyBvciBkZWNyZWFzZXMgZGVwdGggKi8KKwlu b2RlX2RlcHRoID0gcGFyZW50X2RlcHRoOworCW5vZGVvZmZzZXQgPSBmZHRfbmV4dF9ub2RlKGR0 Yiwgbm9kZW9mZnNldCwgJm5vZGVfZGVwdGgpOworCWlmIChyZXQgPCAwKSB7CisJCWRiZ3ByaW50 ZigiVW5hYmxlIHRvIGdldCBuZXh0IG5vZGU6ICVzXG4iLAorCQkJICBmZHRfc3RyZXJyb3IocmV0 KSk7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCXdoaWxlIChub2RlX2RlcHRoICE9IHBhcmVu dF9kZXB0aCkgeworCisJCXJldCA9IGR0Yl9hZGRfbWVtb3J5X3JlZ2lvbihkdGIsIG5vZGVvZmZz ZXQsCisJCQkJCSAgICBtZW1fcmFuZ2VzLCBSQU5HRV9SRVNFUlZFRCk7CisJCWlmIChyZXQpCisJ CQlyZXR1cm4gcmV0OworCisJCW5vZGVvZmZzZXQgPSBmZHRfbmV4dF9ub2RlKGR0Yiwgbm9kZW9m ZnNldCwgJm5vZGVfZGVwdGgpOworCQlpZiAocmV0IDwgMCkgeworCQkJZGJncHJpbnRmKCJVbmFi bGUgdG8gZ2V0IG5leHQgbm9kZTogJXNcbiIsCisJCQkJICBmZHRfc3RyZXJyb3IocmV0KSk7CisJ CQlyZXR1cm4gLUVJTlZBTDsKKwkJfQorCX0KKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50 IGR0Yl9wYXJzZV9tZW1vcnlfbm9kZXMoY2hhciAqZHRiLCBzdHJ1Y3QgbWVtb3J5X3JhbmdlcyAq bWVtX3JhbmdlcykKK3sKKwlpbnQgbm9kZW9mZnNldCA9IDA7CisJaW50IG51bV9yZWdpb25zID0g MDsKKwljb25zdCBjaGFyKiBkZXZfdHlwZSA9IDA7CisJaW50IHByb3Bfc2l6ZSA9IDA7CisJaW50 IHJldCA9IDA7CisKKwlmb3IgKDsgOyBudW1fcmVnaW9ucysrKSB7CisJCW5vZGVvZmZzZXQgPSBm ZHRfc3Vibm9kZV9vZmZzZXQoZHRiLCBub2Rlb2Zmc2V0LAorCQkJCQkJICJtZW1vcnkiKTsKKwkJ aWYgKG5vZGVvZmZzZXQgPCAwKQorCQkJYnJlYWs7CisKKwkJZGJncHJpbnRmKCJHb3QgbWVtb3J5 IG5vZGUgYXQgZGVwdGg6ICVpXG4iLCBmZHRfbm9kZV9kZXB0aChkdGIsIG5vZGVvZmZzZXQpKTsK KworCQkvKiBMb29rIGZvciB0aGUgZGV2aWNlX3R5cGUgIHByb3BlcnR5ICovCisJCWRldl90eXBl ID0gZmR0X2dldHByb3AoZHRiLCBub2Rlb2Zmc2V0LCAiZGV2aWNlX3R5cGUiLCAmcHJvcF9zaXpl KTsKKwkJaWYgKHByb3Bfc2l6ZSA8IDApIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiTWFsZm9ybWVk IC9tZW1vcnkgbm9kZSAobm8gZGV2aWNlLXR5cGUgcHJvcGVydHkpICFcbiIpOworCQkJcmV0dXJu IC1FSU5WQUw7CisJCX0KKworCQlpZiAoc3RybmNtcChkZXZfdHlwZSwgIm1lbW9yeSIsIHByb3Bf c2l6ZSkpIHsKKwkJCWRiZ3ByaW50ZigiR290IHVua25vd24gZGV2X3R5cGUgcHJvcGVydHk6ICVz XG4iLCBkZXZfdHlwZSk7CisJCQljb250aW51ZTsKKwkJfQorCisJCXJldCA9IGR0Yl9hZGRfbWVt b3J5X3JlZ2lvbihkdGIsIG5vZGVvZmZzZXQsIG1lbV9yYW5nZXMsIFJBTkdFX1JBTSk7CisJCWlm IChyZXQpCisJCQlyZXR1cm4gcmV0OworCX0KKworCWlmICghbnVtX3JlZ2lvbnMpIHsKKwkJZGJn cHJpbnRmKCJNYWxmb3JtZWQgZHRiLCBubyAvbWVtb3J5IG5vZGVzIHByZXNlbnQgIVxuIik7CisJ CXJldHVybiAtRUlOVkFMOworCX0KKworCWRiZ3ByaW50ZigiR290ICVpIC9tZW1vcnkgbm9kZXNc biIsIG51bV9yZWdpb25zKTsKKworCXJldHVybiAwOworfQorCitpbnQgZHRiX2dldF9tZW1vcnlf cmFuZ2VzKGNoYXIgKmR0Yiwgc3RydWN0IG1lbW9yeV9yYW5nZXMgKm1lbV9yYW5nZXMsIHN0cnVj dCBtZW1vcnlfcmFuZ2VzICpleHRyYV9yYW5nZXMpCit7CisJaW50IGkgPSAwOworCWludCByZXQg PSAwOworCisJLyogRmlsbCBtZW1fcmFuZ2VzW10gYnkgcGFyc2luZyB0aGUgZGV2aWNlIHRyZWUg Ki8KKwlyZXQgPSBkdGJfcGFyc2VfbWVtb3J5X25vZGVzKGR0YiwgbWVtX3Jhbmdlcyk7CisJaWYg KHJldCkKKwkJcmV0dXJuIHJldDsKKworCXJldCA9IGR0Yl9wYXJzZV9tZW1vcnlfcmVzZXJ2YXRp b25zX3RhYmxlKGR0YiwgbWVtX3Jhbmdlcyk7CisJaWYgKHJldCkKKwkJcmV0dXJuIHJldDsKKwor CXJldCA9IGR0Yl9wYXJzZV9yZXNlcnZlZF9tZW1vcnlfbm9kZShkdGIsIG1lbV9yYW5nZXMpOwor CWlmIChyZXQpCisJCXJldHVybiByZXQ7CisKKwkvKiBBcHBlbmQgYW55IGV4dHJhIHJhbmdlcyBw cm92aWRlZCBieSB0aGUgY2FsbGVyIChlLmcuIGluaXRyZCkgKi8KKwlmb3IgKGkgPSAwOyBleHRy YV9yYW5nZXMgIT0gTlVMTCAmJiBpIDwgZXh0cmFfcmFuZ2VzLT5zaXplOyBpKyspIHsKKwkJZGJn cHJpbnRmKCJBZGRpbmcgZXh0cmEgcmFuZ2U6IDB4JWxseCAtIDB4JWxseCAoJXMpXG4iLAorCQkJ ICBleHRyYV9yYW5nZXMtPnJhbmdlc1tpXS5zdGFydCwKKwkJCSAgZXh0cmFfcmFuZ2VzLT5yYW5n ZXNbaV0uZW5kLAorCQkJICBleHRyYV9yYW5nZXMtPnJhbmdlc1tpXS50eXBlID09IFJBTkdFX1JF U0VSVkVEID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgIlJBTkdFX1JFU0VSVkVEIiA6ICJS QU5HRV9SQU0iKTsKKworCQlyZXQgPSBkdGJfYWRkX21lbW9yeV9yYW5nZShtZW1fcmFuZ2VzLCBl eHRyYV9yYW5nZXMtPnJhbmdlc1tpXS5zdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgZXh0cmFfcmFuZ2VzLT5yYW5nZXNbaV0uZW5kLCBleHRyYV9yYW5nZXMtPnJhbmdlc1tp XS50eXBlKTsKKwkJaWYgKHJldCkKKwkJCXJldHVybiByZXQ7CisJfQorCisJbWVtX3JlZ2lvbnNf c29ydChtZW1fcmFuZ2VzKTsKKworCXJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEva2V4ZWMvZHQt b3BzLmggYi9rZXhlYy9kdC1vcHMuaAppbmRleCAwMzY1OWNlMjgzZGIuLjMwMTQyMDVkOGU5OCAx MDA2NDQKLS0tIGEva2V4ZWMvZHQtb3BzLmgKKysrIGIva2V4ZWMvZHQtb3BzLmgKQEAgLTExLDQg KzExLDExIEBAIGludCBkdGJfc2V0X3Byb3BlcnR5KGNoYXIgKipkdGIsIG9mZl90ICpkdGJfc2l6 ZSwgY29uc3QgY2hhciAqbm9kZSwKIAogaW50IGR0Yl9kZWxldGVfcHJvcGVydHkoY2hhciAqZHRi LCBjb25zdCBjaGFyICpub2RlLCBjb25zdCBjaGFyICpwcm9wKTsKIAordm9pZCBkdGJfZXh0cmFj dF9pbnRfcHJvcGVydHkodWludDY0X3QgKnZhbCwgY29uc3Qgdm9pZCAqYnVmLCB1aW50MzJfdCBj ZWxscyk7Cit2b2lkIGR0Yl9maWxsX2ludF9wcm9wZXJ0eSh2b2lkICpidWYsIHVpbnQ2NF90IHZh bCwgdWludDMyX3QgY2VsbHMpOworaW50IGR0Yl9hZGRfcmFuZ2VfcHJvcGVydHkoY2hhciAqKmR0 Yiwgb2ZmX3QgKmR0Yl9zaXplLCB1aW50NjRfdCBzdGFydCwgdWludDY0X3QgZW5kLAorICAgICAg ICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbm9kZSwgY29uc3QgY2hhciogcGFyZW50 KTsKK2ludCBkdGJfZ2V0X21lbW9yeV9yYW5nZXMoY2hhciAqZHRiLCBzdHJ1Y3QgbWVtb3J5X3Jh bmdlcyAqbWVtX3JhbmdlcywKKwkJCSAgc3RydWN0IG1lbW9yeV9yYW5nZXMgKmV4dHJhX3Jhbmdl cyk7CisKICNlbmRpZgpkaWZmIC0tZ2l0IGEva2V4ZWMva2V4ZWMtc3lzY2FsbC5oIGIva2V4ZWMv a2V4ZWMtc3lzY2FsbC5oCmluZGV4IGNjMzJjMDE2MmFlYy4uODk1OTFhZDE3ZTdkIDEwMDY0NAot LS0gYS9rZXhlYy9rZXhlYy1zeXNjYWxsLmgKKysrIGIva2V4ZWMva2V4ZWMtc3lzY2FsbC5oCkBA IC0xNDAsNiArMTQwLDcgQEAgc3RhdGljIGlubGluZSBsb25nIGtleGVjX2ZpbGVfbG9hZChpbnQg a2VybmVsX2ZkLCBpbnQgaW5pdHJkX2ZkLAogI2RlZmluZSBLRVhFQ19BUkNIX01JUFNfTEUgKDEw IDw8IDE2KQogI2RlZmluZSBLRVhFQ19BUkNIX01JUFMgICAgKCA4IDw8IDE2KQogI2RlZmluZSBL RVhFQ19BUkNIX0NSSVMgICAgKDc2IDw8IDE2KQorI2RlZmluZSBLRVhFQ19BUkNIX1JJU0NWICAg KDI0MyA8PCAxNikKICNkZWZpbmUgS0VYRUNfQVJDSF9MT09OR0FSQ0gJKDI1OCA8PCAxNikKIAog I2RlZmluZSBLRVhFQ19NQVhfU0VHTUVOVFMgMTYKQEAgLTE4Nyw1ICsxODgsOCBAQCBzdGF0aWMg aW5saW5lIGxvbmcga2V4ZWNfZmlsZV9sb2FkKGludCBrZXJuZWxfZmQsIGludCBpbml0cmRfZmQs CiAjaWYgZGVmaW5lZChfX2xvb25nYXJjaF9fKQogI2RlZmluZSBLRVhFQ19BUkNIX05BVElWRQlL RVhFQ19BUkNIX0xPT05HQVJDSAogI2VuZGlmCisjaWYgZGVmaW5lZChfX3Jpc2N2X18pIHx8IGRl ZmluZWQoX19yaXNjdikKKyNkZWZpbmUgS0VYRUNfQVJDSF9OQVRJVkUJS0VYRUNfQVJDSF9SSVND VgorI2VuZGlmCiAKICNlbmRpZiAvKiBLRVhFQ19TWVNDQUxMX0ggKi8KZGlmZiAtLWdpdCBhL3B1 cmdhdG9yeS9NYWtlZmlsZSBiL3B1cmdhdG9yeS9NYWtlZmlsZQppbmRleCA0ZDJkMDcxMzRiZDUu LjdkMTE3NWYyNDQ1YyAxMDA2NDQKLS0tIGEvcHVyZ2F0b3J5L01ha2VmaWxlCisrKyBiL3B1cmdh dG9yeS9NYWtlZmlsZQpAQCAtMjUsNiArMjUsNyBAQCBpbmNsdWRlICQoc3JjZGlyKS9wdXJnYXRv cnkvYXJjaC9pYTY0L01ha2VmaWxlCiBpbmNsdWRlICQoc3JjZGlyKS9wdXJnYXRvcnkvYXJjaC9t aXBzL01ha2VmaWxlCiBpbmNsdWRlICQoc3JjZGlyKS9wdXJnYXRvcnkvYXJjaC9wcGMvTWFrZWZp bGUKIGluY2x1ZGUgJChzcmNkaXIpL3B1cmdhdG9yeS9hcmNoL3BwYzY0L01ha2VmaWxlCitpbmNs dWRlICQoc3JjZGlyKS9wdXJnYXRvcnkvYXJjaC9yaXNjdi9NYWtlZmlsZQogaW5jbHVkZSAkKHNy Y2RpcikvcHVyZ2F0b3J5L2FyY2gvczM5MC9NYWtlZmlsZQogaW5jbHVkZSAkKHNyY2RpcikvcHVy Z2F0b3J5L2FyY2gvc2gvTWFrZWZpbGUKIGluY2x1ZGUgJChzcmNkaXIpL3B1cmdhdG9yeS9hcmNo L3g4Nl82NC9NYWtlZmlsZQpkaWZmIC0tZ2l0IGEvcHVyZ2F0b3J5L2FyY2gvcmlzY3YvTWFrZWZp bGUgYi9wdXJnYXRvcnkvYXJjaC9yaXNjdi9NYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NApp bmRleCAwMDAwMDAwMDAwMDAuLjQ5YTZmZWY0YTkwNAotLS0gL2Rldi9udWxsCisrKyBiL3B1cmdh dG9yeS9hcmNoL3Jpc2N2L01ha2VmaWxlCkBAIC0wLDAgKzEsNyBAQAorIworIyBQdXJnYXRvcnkg cmlzY3YKKyMKKworcmlzY3ZfUFVSR0FUT1JZX1NSQ1MgPQorCitkaXN0ICs9IHB1cmdhdG9yeS9h cmNoL3Jpc2N2L01ha2VmaWxlICQocmlzY3ZfUFVSR0FUT1JZX1NSQ1MpCi0tIAoyLjQ4LjEKCgpf X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1yaXNj diBtYWlsaW5nIGxpc3QKbGludXgtcmlzY3ZAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlz dHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LXJpc2N2Cg==